mirror of
https://github.com/dlang/dmd.git
synced 2025-04-26 13:10:12 +03:00
wrong register mask for cssave() (#21037)
This commit is contained in:
parent
cfefcdd657
commit
996de2ad3a
5 changed files with 23 additions and 20 deletions
|
@ -1435,9 +1435,9 @@ void cdfunc(ref CGstate cg, ref CodeBuilder cdb, elem* e, ref regm_t pretregs)
|
||||||
/* stack for parameters is allocated all at once - no pushing
|
/* stack for parameters is allocated all at once - no pushing
|
||||||
* and ensure it is aligned
|
* and ensure it is aligned
|
||||||
*/
|
*/
|
||||||
printf("STACKALIGN: %d\n", STACKALIGN);
|
//printf("STACKALIGN: %d\n", STACKALIGN);
|
||||||
uint numalign = -numpara & (STACKALIGN - 1);
|
uint numalign = -numpara & (STACKALIGN - 1);
|
||||||
printf("numalign: %d numpara: %d\n", numalign, numpara);
|
//printf("numalign: %d numpara: %d\n", numalign, numpara);
|
||||||
cod3_stackadj(cdb, numalign + numpara);
|
cod3_stackadj(cdb, numalign + numpara);
|
||||||
cdb.genadjesp(numalign + numpara);
|
cdb.genadjesp(numalign + numpara);
|
||||||
cgstate.stackpush += numalign + numpara;
|
cgstate.stackpush += numalign + numpara;
|
||||||
|
|
|
@ -453,14 +453,13 @@ void cdcom(ref CGstate cg, ref CodeBuilder cdb,elem* e,ref regm_t pretregs)
|
||||||
assert(0);
|
assert(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
const posregs = cgstate.allregs;
|
regm_t retregs1 = cg.allregs;
|
||||||
regm_t retregs1 = posregs;
|
|
||||||
codelem(cgstate,cdb,e.E1,retregs1,false);
|
codelem(cgstate,cdb,e.E1,retregs1,false);
|
||||||
|
|
||||||
regm_t retregs = pretregs & cg.allregs;
|
regm_t retregs = pretregs & cg.allregs;
|
||||||
if (retregs == 0) /* if no return regs speced */
|
if (retregs == 0) /* if no return regs speced */
|
||||||
/* (like if wanted flags only) */
|
/* (like if wanted flags only) */
|
||||||
retregs = ALLREGS & posregs; // give us some
|
retregs = cg.allregs; // give us some
|
||||||
reg_t Rd = allocreg(cdb, retregs, tyml);
|
reg_t Rd = allocreg(cdb, retregs, tyml);
|
||||||
|
|
||||||
const Rm = findreg(retregs1);
|
const Rm = findreg(retregs1);
|
||||||
|
|
|
@ -81,6 +81,7 @@ struct CSE
|
||||||
@trusted
|
@trusted
|
||||||
static CSE* add()
|
static CSE* add()
|
||||||
{
|
{
|
||||||
|
//printf("CSE.add()\n");
|
||||||
foreach (ref cse; csextab)
|
foreach (ref cse; csextab)
|
||||||
{
|
{
|
||||||
if (cse.e == null) // can share with previously used one
|
if (cse.e == null) // can share with previously used one
|
||||||
|
@ -170,6 +171,7 @@ struct CSE
|
||||||
@trusted
|
@trusted
|
||||||
static void remove(const elem* e)
|
static void remove(const elem* e)
|
||||||
{
|
{
|
||||||
|
//printf("CSE.remove() e: %p\n", e);
|
||||||
foreach (ref cse; csextab[])
|
foreach (ref cse; csextab[])
|
||||||
{
|
{
|
||||||
if (cse.e == e)
|
if (cse.e == e)
|
||||||
|
|
|
@ -1837,7 +1837,7 @@ void useregs(regm_t regm)
|
||||||
@trusted
|
@trusted
|
||||||
void getregs(ref CodeBuilder cdb, regm_t r)
|
void getregs(ref CodeBuilder cdb, regm_t r)
|
||||||
{
|
{
|
||||||
//printf("getregs(x%x) %s\n", r, regm_str(r));
|
//printf("getregs() %s\n", regm_str(r));
|
||||||
regm_t ms = r & cgstate.regcon.cse.mops; // mask of common subs we must save
|
regm_t ms = r & cgstate.regcon.cse.mops; // mask of common subs we must save
|
||||||
useregs(r);
|
useregs(r);
|
||||||
cgstate.regcon.cse.mval &= ~r;
|
cgstate.regcon.cse.mval &= ~r;
|
||||||
|
@ -1869,6 +1869,7 @@ void getregsNoSave(regm_t r)
|
||||||
@trusted
|
@trusted
|
||||||
private void cse_save(ref CodeBuilder cdb, regm_t ms)
|
private void cse_save(ref CodeBuilder cdb, regm_t ms)
|
||||||
{
|
{
|
||||||
|
//printf("cse_save() ms: %s\n", regm_str(ms));
|
||||||
assert((ms & cgstate.regcon.cse.mops) == ms);
|
assert((ms & cgstate.regcon.cse.mops) == ms);
|
||||||
cgstate.regcon.cse.mops &= ~ms;
|
cgstate.regcon.cse.mops &= ~ms;
|
||||||
|
|
||||||
|
@ -1959,6 +1960,7 @@ void cse_flush(ref CodeBuilder cdb, int do87)
|
||||||
@trusted
|
@trusted
|
||||||
bool cssave(elem* e, regm_t regm, bool opsflag)
|
bool cssave(elem* e, regm_t regm, bool opsflag)
|
||||||
{
|
{
|
||||||
|
//printf("cssave() e: %p regm: %s opsflag: %d\n", e, regm_str(regm), opsflag);
|
||||||
bool result = false;
|
bool result = false;
|
||||||
|
|
||||||
/*if (e.Ecount && e.Ecount == e.Ecomsub)*/
|
/*if (e.Ecount && e.Ecount == e.Ecomsub)*/
|
||||||
|
@ -1968,8 +1970,10 @@ bool cssave(elem* e, regm_t regm, bool opsflag)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
//printf("cssave(e = %p, regm = %s, opsflag = x%x)\n", e, regm_str(regm), opsflag);
|
//printf("cssave(e = %p, regm = %s, opsflag = x%x)\n", e, regm_str(regm), opsflag);
|
||||||
|
if (cgstate.AArch64)
|
||||||
|
regm &= cgstate.allregs | INSTR.FLOATREGS;
|
||||||
|
else
|
||||||
regm &= mBP | ALLREGS | mES | XMMREGS; /* just to be sure */
|
regm &= mBP | ALLREGS | mES | XMMREGS; /* just to be sure */
|
||||||
|
|
||||||
/+
|
/+
|
||||||
/* Do not register CSEs if they are register variables and */
|
/* Do not register CSEs if they are register variables and */
|
||||||
/* are not operator nodes. This forces the register allocation */
|
/* are not operator nodes. This forces the register allocation */
|
||||||
|
@ -2089,10 +2093,6 @@ regm_t getscratch()
|
||||||
@trusted
|
@trusted
|
||||||
private void comsub(ref CodeBuilder cdb,elem* e, ref regm_t pretregs)
|
private void comsub(ref CodeBuilder cdb,elem* e, ref regm_t pretregs)
|
||||||
{
|
{
|
||||||
tym_t tym;
|
|
||||||
regm_t regm,emask;
|
|
||||||
reg_t reg;
|
|
||||||
uint byte_,sz;
|
|
||||||
const AArch64 = cgstate.AArch64;
|
const AArch64 = cgstate.AArch64;
|
||||||
|
|
||||||
//printf("comsub(e = %p, pretregs = %s)\n",e,regm_str(pretregs));
|
//printf("comsub(e = %p, pretregs = %s)\n",e,regm_str(pretregs));
|
||||||
|
@ -2114,7 +2114,7 @@ private void comsub(ref CodeBuilder cdb,elem* e, ref regm_t pretregs)
|
||||||
/* First construct a mask, emask, of all the registers that
|
/* First construct a mask, emask, of all the registers that
|
||||||
* have the right contents.
|
* have the right contents.
|
||||||
*/
|
*/
|
||||||
emask = 0;
|
regm_t emask = 0;
|
||||||
foreach (i, ref v; cgstate.regcon.cse.value[])
|
foreach (i, ref v; cgstate.regcon.cse.value[])
|
||||||
{
|
{
|
||||||
//printf("regcon.cse.value[%d] = %p\n",cast(int)i,v);
|
//printf("regcon.cse.value[%d] = %p\n",cast(int)i,v);
|
||||||
|
@ -2157,16 +2157,16 @@ private void comsub(ref CodeBuilder cdb,elem* e, ref regm_t pretregs)
|
||||||
elem_print(cgstate.regcon.cse.value[0]);
|
elem_print(cgstate.regcon.cse.value[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
tym = tybasic(e.Ety);
|
tym_t tym = tybasic(e.Ety);
|
||||||
sz = _tysize[tym];
|
uint sz = _tysize[tym];
|
||||||
byte_ = sz == 1;
|
uint byte_ = sz == 1;
|
||||||
|
|
||||||
if (sz <= REGSIZE ||
|
if (sz <= REGSIZE ||
|
||||||
(!AArch64 && tyxmmreg(tym) && config.fpxmmregs)) // if data will fit in one register
|
(!AArch64 && tyxmmreg(tym) && config.fpxmmregs)) // if data will fit in one register
|
||||||
{
|
{
|
||||||
/* First see if it is already in a correct register */
|
/* First see if it is already in a correct register */
|
||||||
|
|
||||||
regm = emask & pretregs;
|
regm_t regm = emask & pretregs;
|
||||||
if (regm == 0)
|
if (regm == 0)
|
||||||
regm = emask; /* try any other register */
|
regm = emask; /* try any other register */
|
||||||
if (regm) /* if it's in a register */
|
if (regm) /* if it's in a register */
|
||||||
|
@ -2185,6 +2185,7 @@ private void comsub(ref CodeBuilder cdb,elem* e, ref regm_t pretregs)
|
||||||
foreach (ref cse; CSE.filter(e))
|
foreach (ref cse; CSE.filter(e))
|
||||||
{
|
{
|
||||||
regm_t retregs;
|
regm_t retregs;
|
||||||
|
reg_t reg;
|
||||||
|
|
||||||
if (cse.flags & CSEsimple)
|
if (cse.flags & CSEsimple)
|
||||||
{
|
{
|
||||||
|
@ -2277,7 +2278,7 @@ private void comsub(ref CodeBuilder cdb,elem* e, ref regm_t pretregs)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Look for right vals in any regs */
|
/* Look for right vals in any regs */
|
||||||
regm = pretregs & mMSW;
|
regm_t regm = pretregs & mMSW;
|
||||||
if (emask & regm)
|
if (emask & regm)
|
||||||
msreg = findreg(emask & regm);
|
msreg = findreg(emask & regm);
|
||||||
else if (emask & mMSW)
|
else if (emask & mMSW)
|
||||||
|
@ -2313,13 +2314,13 @@ private void comsub(ref CodeBuilder cdb,elem* e, ref regm_t pretregs)
|
||||||
if (((csemask | emask) & DOUBLEREGS_16) == DOUBLEREGS_16)
|
if (((csemask | emask) & DOUBLEREGS_16) == DOUBLEREGS_16)
|
||||||
{
|
{
|
||||||
immutable reg_t[4] dblreg = [ BX,DX,NOREG,CX ];
|
immutable reg_t[4] dblreg = [ BX,DX,NOREG,CX ];
|
||||||
for (reg = 0; reg != NOREG; reg = dblreg[reg])
|
for (reg_t reg = 0; reg != NOREG; reg = dblreg[reg])
|
||||||
{
|
{
|
||||||
assert(cast(int) reg >= 0 && reg <= 7);
|
assert(cast(int) reg >= 0 && reg <= 7);
|
||||||
if (mask(reg) & csemask)
|
if (mask(reg) & csemask)
|
||||||
loadcse(cdb,e,reg,mask(reg));
|
loadcse(cdb,e,reg,mask(reg));
|
||||||
}
|
}
|
||||||
regm = DOUBLEREGS_16;
|
regm_t regm = DOUBLEREGS_16;
|
||||||
fixresult(cdb,e,regm,pretregs);
|
fixresult(cdb,e,regm,pretregs);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -2174,6 +2174,7 @@ void cdnot(ref CGstate cg, ref CodeBuilder cdb,elem* e,ref regm_t pretregs)
|
||||||
@trusted
|
@trusted
|
||||||
void cdcom(ref CGstate cg, ref CodeBuilder cdb,elem* e,ref regm_t pretregs)
|
void cdcom(ref CGstate cg, ref CodeBuilder cdb,elem* e,ref regm_t pretregs)
|
||||||
{
|
{
|
||||||
|
//printf("cdcom() pretregs: %s\n", regm_str(pretregs));
|
||||||
if (cg.AArch64)
|
if (cg.AArch64)
|
||||||
return dmd.backend.arm.cod2.cdcom(cg, cdb, e, pretregs);
|
return dmd.backend.arm.cod2.cdcom(cg, cdb, e, pretregs);
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue