wrong register mask for cssave() (#21037)

This commit is contained in:
Walter Bright 2025-03-20 01:03:47 -07:00 committed by GitHub
parent cfefcdd657
commit 996de2ad3a
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 23 additions and 20 deletions

View file

@ -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;

View file

@ -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);

View file

@ -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)

View file

@ -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;
} }

View file

@ -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);