make scodelem() and codelem() pass by ref (#16736)

This commit is contained in:
Walter Bright 2024-07-20 04:36:49 -07:00 committed by GitHub
parent e11e0eacea
commit e7f132a0ab
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 90 additions and 79 deletions

View file

@ -958,7 +958,7 @@ void orth87(ref CodeBuilder cdb,elem *e,ref regm_t pretregs)
{ {
// Perform "mul 2.0" as fadd ST(0), ST // Perform "mul 2.0" as fadd ST(0), ST
regm_t retregs = mST0; regm_t retregs = mST0;
codelem(cgstate,cdb,e1,&retregs,false); codelem(cgstate,cdb,e1,retregs,false);
cdb.genf2(0xDC, 0xC0); // fadd ST(0), ST; cdb.genf2(0xDC, 0xC0); // fadd ST(0), ST;
fixresult87(cdb,e,mST0,pretregs); // result is in ST(0). fixresult87(cdb,e,mST0,pretregs); // result is in ST(0).
freenode(e2); freenode(e2);
@ -1053,7 +1053,7 @@ void orth87(ref CodeBuilder cdb,elem *e,ref regm_t pretregs)
assert(OTrel(e.Eoper)); assert(OTrel(e.Eoper));
assert((pretregs & mST0) == 0); assert((pretregs & mST0) == 0);
regm_t retregs = mST0; regm_t retregs = mST0;
codelem(cgstate,cdb,e1,&retregs,false); codelem(cgstate,cdb,e1,retregs,false);
note87(e1,0,0); note87(e1,0,0);
regm_t resregm = mPSW; regm_t resregm = mPSW;
@ -1221,7 +1221,7 @@ void orth87(ref CodeBuilder cdb,elem *e,ref regm_t pretregs)
Lcomplex2: Lcomplex2:
{ {
regm_t retregs = mST0; regm_t retregs = mST0;
codelem(cgstate,cdb,e1, &retregs, false); codelem(cgstate,cdb,e1, retregs, false);
note87(e1, 0, 0); note87(e1, 0, 0);
loadComplex(cdb,e2); loadComplex(cdb,e2);
makesure87(cdb, e1, 0, 2, 0); makesure87(cdb, e1, 0, 2, 0);
@ -1289,9 +1289,9 @@ void orth87(ref CodeBuilder cdb,elem *e,ref regm_t pretregs)
case X(OPmin, TYildouble, TYldouble): case X(OPmin, TYildouble, TYldouble):
{ {
regm_t retregs = mST0; regm_t retregs = mST0;
codelem(cgstate,cdb,e1, &retregs, false); codelem(cgstate,cdb,e1, retregs, false);
note87(e1, 0, 0); note87(e1, 0, 0);
codelem(cgstate,cdb,e2, &retregs, false); codelem(cgstate,cdb,e2, retregs, false);
makesure87(cdb, e1, 0, 1, 0); makesure87(cdb, e1, 0, 1, 0);
if (eoper == OPmin) if (eoper == OPmin)
cdb.genf2(0xD9, 0xE0); // FCHS cdb.genf2(0xD9, 0xE0); // FCHS
@ -1351,7 +1351,7 @@ void orth87(ref CodeBuilder cdb,elem *e,ref regm_t pretregs)
} }
} }
regm_t retregs = mST0; regm_t retregs = mST0;
codelem(cgstate,cdb,e2, &retregs, false); codelem(cgstate,cdb,e2, retregs, false);
makesure87(cdb, e1, sz2, 1, 0); makesure87(cdb, e1, sz2, 1, 0);
makesure87(cdb, e1, 0, 2, 0); makesure87(cdb, e1, 0, 2, 0);
cdb.genf2(0xDC,0xC8 + 2); // FMUL ST(2), ST cdb.genf2(0xDC,0xC8 + 2); // FMUL ST(2), ST
@ -1374,7 +1374,7 @@ void orth87(ref CodeBuilder cdb,elem *e,ref regm_t pretregs)
Lcmul2: Lcmul2:
{ {
regm_t retregs = mST0; regm_t retregs = mST0;
codelem(cgstate,cdb,e1, &retregs, false); codelem(cgstate,cdb,e1, retregs, false);
note87(e1, 0, 0); note87(e1, 0, 0);
loadComplex(cdb,e2); loadComplex(cdb,e2);
makesure87(cdb, e1, 0, 2, 0); makesure87(cdb, e1, 0, 2, 0);
@ -1393,7 +1393,7 @@ void orth87(ref CodeBuilder cdb,elem *e,ref regm_t pretregs)
{ {
loadComplex(cdb,e1); loadComplex(cdb,e1);
regm_t retregs = mST0; regm_t retregs = mST0;
codelem(cgstate,cdb,e2, &retregs, false); codelem(cgstate,cdb,e2, retregs, false);
makesure87(cdb, e1, sz2, 1, 0); makesure87(cdb, e1, sz2, 1, 0);
makesure87(cdb, e1, 0, 2, 0); makesure87(cdb, e1, 0, 2, 0);
cdb.genf2(0xDC,0xF8 + 2); // FDIV ST(2), ST cdb.genf2(0xDC,0xF8 + 2); // FDIV ST(2), ST
@ -1412,7 +1412,7 @@ void orth87(ref CodeBuilder cdb,elem *e,ref regm_t pretregs)
xchg87(0, 1); xchg87(0, 1);
cdb.genf2(0xD9, 0xE0); // FCHS cdb.genf2(0xD9, 0xE0); // FCHS
regm_t retregs = mST0; regm_t retregs = mST0;
codelem(cgstate,cdb,e2, &retregs, false); codelem(cgstate,cdb,e2, retregs, false);
makesure87(cdb, e1, 0, 1, 0); makesure87(cdb, e1, 0, 1, 0);
makesure87(cdb, e1, sz2, 2, 0); makesure87(cdb, e1, sz2, 2, 0);
cdb.genf2(0xDC,0xF8 + 2); // FDIV ST(2), ST cdb.genf2(0xDC,0xF8 + 2); // FDIV ST(2), ST
@ -1450,7 +1450,7 @@ void orth87(ref CodeBuilder cdb,elem *e,ref regm_t pretregs)
*/ */
loadComplex(cdb,e1); loadComplex(cdb,e1);
regm_t retregs = mST0; regm_t retregs = mST0;
codelem(cgstate,cdb,e2, &retregs, false); codelem(cgstate,cdb,e2, retregs, false);
makesure87(cdb, e1, sz2, 1, 0); makesure87(cdb, e1, sz2, 1, 0);
makesure87(cdb, e1, 0, 2, 0); makesure87(cdb, e1, 0, 2, 0);
cdb.genf2(0xD9, 0xC8 + 1); // FXCH ST(1) cdb.genf2(0xD9, 0xC8 + 1); // FXCH ST(1)
@ -1510,7 +1510,7 @@ void orth87(ref CodeBuilder cdb,elem *e,ref regm_t pretregs)
} }
regm_t retregs1 = mST0; regm_t retregs1 = mST0;
codelem(cgstate,cdb,e1,&retregs1,false); codelem(cgstate,cdb,e1,retregs1,false);
note87(e1,0,0); note87(e1,0,0);
if (config.flags4 & CFG4fdivcall && e.Eoper == OPdiv) if (config.flags4 & CFG4fdivcall && e.Eoper == OPdiv)
@ -1582,7 +1582,7 @@ private void loadComplex(ref CodeBuilder cdb,elem *e)
case TYdouble: case TYdouble:
case TYldouble: case TYldouble:
retregs = mST0; retregs = mST0;
codelem(cgstate,cdb,e,&retregs,false); codelem(cgstate,cdb,e,retregs,false);
// Convert to complex with a 0 for the imaginary part // Convert to complex with a 0 for the imaginary part
push87(cdb); push87(cdb);
cdb.gen2(0xD9,0xEE); // FLDZ cdb.gen2(0xD9,0xEE); // FLDZ
@ -1595,7 +1595,7 @@ private void loadComplex(ref CodeBuilder cdb,elem *e)
push87(cdb); push87(cdb);
cdb.gen2(0xD9,0xEE); // FLDZ cdb.gen2(0xD9,0xEE); // FLDZ
retregs = mST0; retregs = mST0;
codelem(cgstate,cdb,e,&retregs,false); codelem(cgstate,cdb,e,retregs,false);
break; break;
case TYcfloat: case TYcfloat:
@ -1603,7 +1603,7 @@ private void loadComplex(ref CodeBuilder cdb,elem *e)
case TYcldouble: case TYcldouble:
sz /= 2; sz /= 2;
retregs = mST01; retregs = mST01;
codelem(cgstate,cdb,e,&retregs,false); codelem(cgstate,cdb,e,retregs,false);
break; break;
default: default:
@ -1748,7 +1748,7 @@ L5:
else else
{ {
retregs = mST0; retregs = mST0;
codelem(cgstate,cdb,e.E1,&retregs,false); codelem(cgstate,cdb,e.E1,retregs,false);
if (op != -1) if (op != -1)
{ {
makesure87(cdb,eleft,eoffset,1,0); makesure87(cdb,eleft,eoffset,1,0);
@ -1775,7 +1775,7 @@ L5:
else if (I64) else if (I64)
{ {
retregs = ALLREGS; retregs = ALLREGS;
codelem(cgstate,cdb,e.E1,&retregs,false); codelem(cgstate,cdb,e.E1,retregs,false);
reg = findreg(retregs); reg = findreg(retregs);
cdb.genfltreg(STO,reg,0); // MOV floatreg,reg cdb.genfltreg(STO,reg,0); // MOV floatreg,reg
code_orrex(cdb.last(), REX_W); code_orrex(cdb.last(), REX_W);
@ -1785,7 +1785,7 @@ L5:
else else
{ {
retregs = ALLREGS; retregs = ALLREGS;
codelem(cgstate,cdb,e.E1,&retregs,false); codelem(cgstate,cdb,e.E1,retregs,false);
reg = findreglsw(retregs); reg = findreglsw(retregs);
cdb.genfltreg(STO,reg,0); // MOV floatreg,reglsw cdb.genfltreg(STO,reg,0); // MOV floatreg,reglsw
reg = findregmsw(retregs); reg = findregmsw(retregs);
@ -1828,7 +1828,7 @@ L5:
if (op != -1 && !noted) if (op != -1 && !noted)
note87(eleft,eoffset,0); // don't trash this value note87(eleft,eoffset,0); // don't trash this value
retregs = ALLREGS & mLSW; retregs = ALLREGS & mLSW;
codelem(cgstate,cdb,e.E1,&retregs,false); codelem(cgstate,cdb,e.E1,retregs,false);
reg = regwithvalue(cdb,ALLREGS & mMSW,0,0); // 0-extend reg = regwithvalue(cdb,ALLREGS & mMSW,0,0); // 0-extend
retregs |= mask(reg); retregs |= mask(reg);
mf1 = MFlong; mf1 = MFlong;
@ -1850,7 +1850,7 @@ L5:
else else
{ {
retregs = ALLREGS; retregs = ALLREGS;
codelem(cgstate,cdb,e.E1,&retregs,false); codelem(cgstate,cdb,e.E1,retregs,false);
L3: L3:
if (I16 && e.Eoper != OPs16_d) if (I16 && e.Eoper != OPs16_d)
{ {
@ -1877,7 +1877,7 @@ L5:
default: default:
Ldefault: Ldefault:
retregs = mST0; retregs = mST0;
codelem(cgstate,cdb,e,&retregs,2); codelem(cgstate,cdb,e,retregs,2);
if (op != -1) if (op != -1)
{ {
@ -1978,7 +1978,7 @@ void eq87(ref CodeBuilder cdb,elem *e,ref regm_t pretregs)
//printf("+eq87(e = %p, pretregs = %s)\n", e, regm_str(pretregs)); //printf("+eq87(e = %p, pretregs = %s)\n", e, regm_str(pretregs));
assert(e.Eoper == OPeq); assert(e.Eoper == OPeq);
regm_t retregs = mST0 | (pretregs & mPSW); regm_t retregs = mST0 | (pretregs & mPSW);
codelem(cgstate,cdb,e.E2,&retregs,false); codelem(cgstate,cdb,e.E2,retregs,false);
tym_t ty1 = tybasic(e.E1.Ety); tym_t ty1 = tybasic(e.E1.Ety);
switch (ty1) switch (ty1)
{ {
@ -2096,7 +2096,7 @@ void complex_eq87(ref CodeBuilder cdb,elem *e,ref regm_t pretregs)
cs.Iflags = ADDFWAIT() ? CFwait : 0; cs.Iflags = ADDFWAIT() ? CFwait : 0;
cs.Irex = 0; cs.Irex = 0;
regm_t retregs = mST01 | (pretregs & mPSW); regm_t retregs = mST01 | (pretregs & mPSW);
codelem(cgstate,cdb,e.E2,&retregs,false); codelem(cgstate,cdb,e.E2,retregs,false);
tym_t ty1 = tybasic(e.E1.Ety); tym_t ty1 = tybasic(e.E1.Ety);
switch (ty1) switch (ty1)
{ {
@ -2213,7 +2213,7 @@ private void cnvteq87(ref CodeBuilder cdb,elem *e,ref regm_t pretregs)
assert(!pretregs); assert(!pretregs);
regm_t retregs = mST0; regm_t retregs = mST0;
elem_debug(e.E2); elem_debug(e.E2);
codelem(cgstate,cdb,e.E2.E1,&retregs,false); codelem(cgstate,cdb,e.E2.E1,retregs,false);
switch (e.E2.Eoper) switch (e.E2.Eoper)
{ case OPd_s16: { case OPd_s16:
@ -2297,7 +2297,7 @@ public void opass87(ref CodeBuilder cdb,elem *e,ref regm_t pretregs)
default: assert(0); default: assert(0);
} }
regm_t retregs = mST0; regm_t retregs = mST0;
codelem(cgstate,cdb,e.E2,&retregs,false); // evaluate rvalue codelem(cgstate,cdb,e.E2,retregs,false); // evaluate rvalue
note87(e.E2,0,0); note87(e.E2,0,0);
getlvalue87(cdb,cs,e.E1,e.Eoper==OPmodass?mAX:0); getlvalue87(cdb,cs,e.E1,e.Eoper==OPmodass?mAX:0);
makesure87(cdb,e.E2,0,0,0); makesure87(cdb,e.E2,0,0,0);
@ -2414,7 +2414,7 @@ private void opmod_complex87(ref CodeBuilder cdb, elem *e,ref regm_t pretregs)
uint sz2 = _tysize[ty1] / 2; uint sz2 = _tysize[ty1] / 2;
regm_t retregs = mST0; regm_t retregs = mST0;
codelem(cgstate,cdb,e.E2,&retregs,false); // FLD E2 codelem(cgstate,cdb,e.E2,retregs,false); // FLD E2
note87(e.E2,0,0); note87(e.E2,0,0);
getlvalue87(cdb,cs,e.E1,0); getlvalue87(cdb,cs,e.E1,0);
makesure87(cdb,e.E2,0,0,0); makesure87(cdb,e.E2,0,0,0);
@ -2511,7 +2511,7 @@ private void opass_complex87(ref CodeBuilder cdb,elem *e,ref regm_t pretregs)
(e.Eoper == OPmulass || e.Eoper == OPdivass)) (e.Eoper == OPmulass || e.Eoper == OPdivass))
{ {
retregs = mST0; retregs = mST0;
codelem(cgstate,cdb,e.E2, &retregs, false); codelem(cgstate,cdb,e.E2, retregs, false);
note87(e.E2, 0, 0); note87(e.E2, 0, 0);
getlvalue87(cdb,cs, e.E1, 0); getlvalue87(cdb,cs, e.E1, 0);
makesure87(cdb,e.E2,0,0,0); makesure87(cdb,e.E2,0,0,0);
@ -2893,7 +2893,7 @@ void post87(ref CodeBuilder cdb,elem *e,ref regm_t pretregs)
cs.IEV1.Voffset += sz; cs.IEV1.Voffset += sz;
cdb.gen(&cs); // FLD e.E1 cdb.gen(&cs); // FLD e.E1
regm_t retregs = mST0; // note kludge to only load real part regm_t retregs = mST0; // note kludge to only load real part
codelem(cgstate,cdb,e.E2,&retregs,false); // load rvalue codelem(cgstate,cdb,e.E2,retregs,false); // load rvalue
cdb.genf2(0xD8, // FADD/FSUBR ST,ST2 cdb.genf2(0xD8, // FADD/FSUBR ST,ST2
(e.Eoper == OPpostinc) ? 0xC0 + 2 : 0xE8 + 2); (e.Eoper == OPpostinc) ? 0xC0 + 2 : 0xE8 + 2);
NEWREG(cs.Irm,reg); NEWREG(cs.Irm,reg);
@ -2914,7 +2914,7 @@ void post87(ref CodeBuilder cdb,elem *e,ref regm_t pretregs)
if (pretregs & mPSW) // if result in flags if (pretregs & mPSW) // if result in flags
genftst(cdb,e,0); // FTST ST0 genftst(cdb,e,0); // FTST ST0
regm_t retregs = mST0; regm_t retregs = mST0;
codelem(cgstate,cdb,e.E2,&retregs,false); // load rvalue codelem(cgstate,cdb,e.E2,retregs,false); // load rvalue
pop87(); pop87();
op = (e.Eoper == OPpostinc) ? modregrm(3,0,1) : modregrm(3,5,1); op = (e.Eoper == OPpostinc) ? modregrm(3,0,1) : modregrm(3,5,1);
cdb.genf2(0xDE,op); // FADDP/FSUBRP ST1 cdb.genf2(0xDE,op); // FADDP/FSUBRP ST1
@ -2973,7 +2973,7 @@ private void cdd_u64_I32(ref CodeBuilder cdb, elem *e, ref regm_t pretregs)
L2: L2:
*/ */
regm_t retregs = mST0; regm_t retregs = mST0;
codelem(cgstate,cdb,e.E1, &retregs, false); codelem(cgstate,cdb,e.E1, retregs, false);
tym_t tym = e.Ety; tym_t tym = e.Ety;
retregs = pretregs; retregs = pretregs;
if (!retregs) if (!retregs)
@ -3057,7 +3057,7 @@ private void cdd_u64_I64(ref CodeBuilder cdb, elem *e, ref regm_t pretregs)
L2: L2:
*/ */
regm_t retregs = mST0; regm_t retregs = mST0;
codelem(cgstate,cdb,e.E1, &retregs, false); codelem(cgstate,cdb,e.E1, retregs, false);
tym_t tym = e.Ety; tym_t tym = e.Ety;
retregs = pretregs; retregs = pretregs;
if (!retregs) if (!retregs)
@ -3129,7 +3129,7 @@ void cdd_u32(ref CodeBuilder cdb, elem *e, ref regm_t pretregs)
mov EAX,floatreg mov EAX,floatreg
*/ */
regm_t retregs = mST0; regm_t retregs = mST0;
codelem(cgstate,cdb,e.E1, &retregs, false); codelem(cgstate,cdb,e.E1, retregs, false);
tym_t tym = e.Ety; tym_t tym = e.Ety;
retregs = pretregs & ALLREGS; retregs = pretregs & ALLREGS;
if (!retregs) if (!retregs)
@ -3212,12 +3212,12 @@ void cnvt87(ref CodeBuilder cdb,elem *e,ref regm_t pretregs)
{ {
if (clib == CLIB.dblllng) if (clib == CLIB.dblllng)
{ retregs = I32 ? DOUBLEREGS_32 : DOUBLEREGS_16; { retregs = I32 ? DOUBLEREGS_32 : DOUBLEREGS_16;
codelem(cgstate,cdb,e.E1,&retregs,false); codelem(cgstate,cdb,e.E1,retregs,false);
callclib(cdb,e,clib,pretregs,0); callclib(cdb,e,clib,pretregs,0);
} }
else else
{ retregs = mST0; //I32 ? DOUBLEREGS_32 : DOUBLEREGS_16; { retregs = mST0; //I32 ? DOUBLEREGS_32 : DOUBLEREGS_16;
codelem(cgstate,cdb,e.E1,&retregs,false); codelem(cgstate,cdb,e.E1,retregs,false);
callclib(cdb,e,clib,pretregs,0); callclib(cdb,e,clib,pretregs,0);
pop87(); pop87();
} }
@ -3239,7 +3239,7 @@ void cnvt87(ref CodeBuilder cdb,elem *e,ref regm_t pretregs)
szpush = (szpush + REGSIZE - 1) & ~(REGSIZE - 1); szpush = (szpush + REGSIZE - 1) & ~(REGSIZE - 1);
retregs = mST0; retregs = mST0;
codelem(cgstate,cdb,e.E1,&retregs,false); codelem(cgstate,cdb,e.E1,retregs,false);
if (szpush == REGSIZE) if (szpush == REGSIZE)
cdb.gen1(0x50 + AX); // PUSH EAX cdb.gen1(0x50 + AX); // PUSH EAX
@ -3289,7 +3289,7 @@ void cnvt87(ref CodeBuilder cdb,elem *e,ref regm_t pretregs)
// negative int (0x80000....). For -inf, 0x7FFFF... should be returned, // negative int (0x80000....). For -inf, 0x7FFFF... should be returned,
// and for nan, 0 should be returned. // and for nan, 0 should be returned.
retregs = mST0; retregs = mST0;
codelem(cgstate,cdb,e.E1,&retregs,false); codelem(cgstate,cdb,e.E1,retregs,false);
genfwait(cdb); genfwait(cdb);
genSetRoundingMode(cdb, CW.roundto0); // FLDCW roundto0 genSetRoundingMode(cdb, CW.roundto0); // FLDCW roundto0
@ -3331,11 +3331,11 @@ void cdrndtol(ref CGstate cg, ref CodeBuilder cdb,elem *e,ref regm_t pretregs)
{ {
if (pretregs == 0) if (pretregs == 0)
{ {
codelem(cgstate,cdb,e.E1,&pretregs,false); codelem(cgstate,cdb,e.E1,pretregs,false);
return; return;
} }
regm_t retregs = mST0; regm_t retregs = mST0;
codelem(cgstate,cdb,e.E1,&retregs,false); codelem(cgstate,cdb,e.E1,retregs,false);
ubyte op1,op2; ubyte op1,op2;
tym_t tym = e.Ety; tym_t tym = e.Ety;
@ -3395,9 +3395,9 @@ void cdscale(ref CGstate cg, ref CodeBuilder cdb,elem *e,ref regm_t pretregs)
assert(pretregs != 0); assert(pretregs != 0);
regm_t retregs = mST0; regm_t retregs = mST0;
codelem(cgstate,cdb,e.E1,&retregs,false); codelem(cgstate,cdb,e.E1,retregs,false);
note87(e.E1,0,0); note87(e.E1,0,0);
codelem(cgstate,cdb,e.E2,&retregs,false); codelem(cgstate,cdb,e.E2,retregs,false);
makesure87(cdb,e.E1,0,1,0); // now have x,y on stack; need y,x makesure87(cdb,e.E1,0,1,0); // now have x,y on stack; need y,x
switch (e.Eoper) switch (e.Eoper)
{ {
@ -3450,7 +3450,7 @@ void neg87(ref CodeBuilder cdb,elem *e,ref regm_t pretregs)
assert(0); assert(0);
} }
regm_t retregs = mST0; regm_t retregs = mST0;
codelem(cgstate,cdb,e.E1,&retregs,false); codelem(cgstate,cdb,e.E1,retregs,false);
cdb.genf2(0xD9,op); // FCHS/FABS/FSQRT/FSIN/FCOS/FRNDINT cdb.genf2(0xD9,op); // FCHS/FABS/FSQRT/FSIN/FCOS/FRNDINT
fixresult87(cdb,e,mST0,pretregs); fixresult87(cdb,e,mST0,pretregs);
} }
@ -3464,7 +3464,7 @@ void neg_complex87(ref CodeBuilder cdb,elem *e,ref regm_t pretregs)
{ {
assert(e.Eoper == OPneg); assert(e.Eoper == OPneg);
regm_t retregs = mST01; regm_t retregs = mST01;
codelem(cgstate,cdb,e.E1,&retregs,false); codelem(cgstate,cdb,e.E1,retregs,false);
cdb.genf2(0xD9,0xE0); // FCHS cdb.genf2(0xD9,0xE0); // FCHS
cdb.genf2(0xD9,0xC8 + 1); // FXCH ST(1) cdb.genf2(0xD9,0xC8 + 1); // FXCH ST(1)
cdb.genf2(0xD9,0xE0); // FCHS cdb.genf2(0xD9,0xE0); // FCHS
@ -3807,7 +3807,7 @@ void cdconvt87(ref CGstate cg, ref CodeBuilder cdb, elem *e, regm_t *pretregs)
void cdconvt87(ref CGstate cg, ref CodeBuilder cdb, elem *e, ref regm_t pretregs) void cdconvt87(ref CGstate cg, ref CodeBuilder cdb, elem *e, ref regm_t pretregs)
{ {
regm_t retregs = mST01; regm_t retregs = mST01;
codelem(cgstate,cdb,e.E1, &retregs, false); codelem(cgstate,cdb,e.E1, retregs, false);
switch (e.Eoper) switch (e.Eoper)
{ {
case OPc_r: case OPc_r:
@ -3936,9 +3936,9 @@ void loadPair87(ref CodeBuilder cdb, elem *e, ref regm_t outretregs)
{ {
assert(e.Eoper == OPpair || e.Eoper == OPrpair); assert(e.Eoper == OPpair || e.Eoper == OPrpair);
regm_t retregs = mST0; regm_t retregs = mST0;
codelem(cgstate,cdb,e.E1, &retregs, false); codelem(cgstate,cdb,e.E1, retregs, false);
note87(e.E1, 0, 0); note87(e.E1, 0, 0);
codelem(cgstate,cdb,e.E2, &retregs, false); codelem(cgstate,cdb,e.E2, retregs, false);
makesure87(cdb,e.E1, 0, 1, 0); makesure87(cdb,e.E1, 0, 1, 0);
if (e.Eoper == OPrpair) if (e.Eoper == OPrpair)
cdb.genf2(0xD9, 0xC8 + 1); // FXCH ST(1) cdb.genf2(0xD9, 0xC8 + 1); // FXCH ST(1)
@ -3962,13 +3962,13 @@ void cdtoprec(ref CGstate cg, ref CodeBuilder cdb, elem* e, ref regm_t pretregs)
//printf("cdtoprec: pretregs = %s\n", regm_str(pretregs)); //printf("cdtoprec: pretregs = %s\n", regm_str(pretregs));
if (!pretregs) if (!pretregs)
{ {
codelem(cgstate,cdb,e.E1,&pretregs,false); codelem(cgstate,cdb,e.E1,pretregs,false);
return; return;
} }
assert(config.inline8087); assert(config.inline8087);
regm_t retregs = mST0; regm_t retregs = mST0;
codelem(cgstate,cdb,e.E1, &retregs, false); codelem(cgstate,cdb,e.E1, retregs, false);
if (pretregs & mST0) if (pretregs & mST0)
{ {
const tym = tybasic(e.Ety); const tym = tybasic(e.Ety);

View file

@ -2575,12 +2575,18 @@ private immutable nothrow void function (ref CGstate, ref CodeBuilder,elem *,reg
*/ */
@trusted @trusted
void codelem(ref CGstate cg, ref CodeBuilder cdb,elem *e,regm_t *pretregs,uint constflag) void codelem(ref CGstate cg, ref CodeBuilder cdb,elem *e,regm_t *pretregs,uint constflag)
{
codelem(cg, cdb, e, *pretregs, constflag);
}
@trusted
void codelem(ref CGstate cg, ref CodeBuilder cdb,elem *e,ref regm_t pretregs,uint constflag)
{ {
Symbol *s; Symbol *s;
debug if (debugw) debug if (debugw)
{ {
printf("+codelem(e=%p,*pretregs=%s) %s ",e,regm_str(*pretregs),oper_str(e.Eoper)); printf("+codelem(e=%p,*pretregs=%s) %s ",e,regm_str(pretregs),oper_str(e.Eoper));
printf("msavereg=%s cg.regcon.cse.mval=%s regcon.cse.mops=%s\n", printf("msavereg=%s cg.regcon.cse.mval=%s regcon.cse.mops=%s\n",
regm_str(cg.msavereg),regm_str(cg.regcon.cse.mval),regm_str(cg.regcon.cse.mops)); regm_str(cg.msavereg),regm_str(cg.regcon.cse.mval),regm_str(cg.regcon.cse.mops));
printf("Ecount = %d, Ecomsub = %d\n", e.Ecount, e.Ecomsub); printf("Ecount = %d, Ecomsub = %d\n", e.Ecount, e.Ecomsub);
@ -2592,7 +2598,7 @@ void codelem(ref CGstate cg, ref CodeBuilder cdb,elem *e,regm_t *pretregs,uint c
{ {
debug debug
{ {
printf("+codelem(e=%p,*pretregs=%s) ", e, regm_str(*pretregs)); printf("+codelem(e=%p,*pretregs=%s) ", e, regm_str(pretregs));
elem_print(e); elem_print(e);
printf("msavereg=%s cg.regcon.cse.mval=%s regcon.cse.mops=%s\n", printf("msavereg=%s cg.regcon.cse.mval=%s regcon.cse.mops=%s\n",
regm_str(cg.msavereg),regm_str(cg.regcon.cse.mval),regm_str(cg.regcon.cse.mops)); regm_str(cg.msavereg),regm_str(cg.regcon.cse.mval),regm_str(cg.regcon.cse.mops));
@ -2601,13 +2607,13 @@ void codelem(ref CGstate cg, ref CodeBuilder cdb,elem *e,regm_t *pretregs,uint c
assert(0); assert(0);
} }
if (!(constflag & 1) && *pretregs & (mES | ALLREGS | mBP | XMMREGS) & ~cg.regcon.mvar) if (!(constflag & 1) && pretregs & (mES | ALLREGS | mBP | XMMREGS) & ~cg.regcon.mvar)
*pretregs &= ~cg.regcon.mvar; /* can't use register vars */ pretregs &= ~cg.regcon.mvar; /* can't use register vars */
uint op = e.Eoper; uint op = e.Eoper;
if (e.Ecount && e.Ecount != e.Ecomsub) // if common subexp if (e.Ecount && e.Ecount != e.Ecomsub) // if common subexp
{ {
comsub(cdb,e, *pretregs); comsub(cdb,e, pretregs);
goto L1; goto L1;
} }
@ -2620,53 +2626,53 @@ void codelem(ref CGstate cg, ref CodeBuilder cdb,elem *e,regm_t *pretregs,uint c
if (e.Ecount) /* if common subexp */ if (e.Ecount) /* if common subexp */
{ {
/* if no return value */ /* if no return value */
if ((*pretregs & (mSTACK | mES | ALLREGS | mBP | XMMREGS)) == 0) if ((pretregs & (mSTACK | mES | ALLREGS | mBP | XMMREGS)) == 0)
{ {
if (*pretregs & (mST0 | mST01)) if (pretregs & (mST0 | mST01))
{ {
//printf("generate ST0 comsub for:\n"); //printf("generate ST0 comsub for:\n");
//elem_print(e); //elem_print(e);
regm_t retregs = *pretregs & mST0 ? mXMM0 : mXMM0|mXMM1; regm_t retregs = pretregs & mST0 ? mXMM0 : mXMM0|mXMM1;
(*cdxxx[op])(cg,cdb,e,&retregs); (*cdxxx[op])(cg,cdb,e,&retregs);
cssave(e,retregs,!OTleaf(op)); cssave(e,retregs,!OTleaf(op));
fixresult(cdb, e, retregs, *pretregs); fixresult(cdb, e, retregs, pretregs);
goto L1; goto L1;
} }
if (tysize(e.Ety) == 1) if (tysize(e.Ety) == 1)
*pretregs |= BYTEREGS; pretregs |= BYTEREGS;
else if ((tyxmmreg(e.Ety) || tysimd(e.Ety)) && config.fpxmmregs) else if ((tyxmmreg(e.Ety) || tysimd(e.Ety)) && config.fpxmmregs)
*pretregs |= XMMREGS; pretregs |= XMMREGS;
else if (tybasic(e.Ety) == TYdouble || tybasic(e.Ety) == TYdouble_alias) else if (tybasic(e.Ety) == TYdouble || tybasic(e.Ety) == TYdouble_alias)
*pretregs |= DOUBLEREGS; pretregs |= DOUBLEREGS;
else else
*pretregs |= ALLREGS; /* make one */ pretregs |= ALLREGS; /* make one */
} }
/* BUG: For CSEs, make sure we have both an MSW */ /* BUG: For CSEs, make sure we have both an MSW */
/* and an LSW specified in *pretregs */ /* and an LSW specified in *pretregs */
} }
assert(op <= OPMAX); assert(op <= OPMAX);
(*cdxxx[op])(cg,cdb,e,pretregs); (*cdxxx[op])(cg,cdb,e,&pretregs);
break; break;
case OPrelconst: case OPrelconst:
cdrelconst(cg, cdb,e,pretregs); cdrelconst(cg, cdb,e,&pretregs);
break; break;
case OPvar: case OPvar:
if (constflag & 1 && (s = e.Vsym).Sfl == FLreg && if (constflag & 1 && (s = e.Vsym).Sfl == FLreg &&
(s.Sregm & *pretregs) == s.Sregm) (s.Sregm & pretregs) == s.Sregm)
{ {
if (tysize(e.Ety) <= REGSIZE && tysize(s.Stype.Tty) == 2 * REGSIZE) if (tysize(e.Ety) <= REGSIZE && tysize(s.Stype.Tty) == 2 * REGSIZE)
*pretregs &= mPSW | (s.Sregm & mLSW); pretregs &= mPSW | (s.Sregm & mLSW);
else else
*pretregs &= mPSW | s.Sregm; pretregs &= mPSW | s.Sregm;
} }
goto case OPconst; goto case OPconst;
case OPconst: case OPconst:
if (*pretregs == 0 && (e.Ecount >= 3 || e.Ety & mTYvolatile)) if (pretregs == 0 && (e.Ecount >= 3 || e.Ety & mTYvolatile))
{ {
switch (tybasic(e.Ety)) switch (tybasic(e.Ety))
{ {
@ -2674,7 +2680,7 @@ void codelem(ref CGstate cg, ref CodeBuilder cdb,elem *e,regm_t *pretregs,uint c
case TYchar: case TYchar:
case TYschar: case TYschar:
case TYuchar: case TYuchar:
*pretregs |= BYTEREGS; pretregs |= BYTEREGS;
break; break;
case TYnref: case TYnref:
@ -2685,7 +2691,7 @@ void codelem(ref CGstate cg, ref CodeBuilder cdb,elem *e,regm_t *pretregs,uint c
case TYimmutPtr: case TYimmutPtr:
case TYsharePtr: case TYsharePtr:
case TYrestrictPtr: case TYrestrictPtr:
*pretregs |= I16 ? IDXREGS : ALLREGS; pretregs |= I16 ? IDXREGS : ALLREGS;
break; break;
case TYshort: case TYshort:
@ -2701,24 +2707,24 @@ void codelem(ref CGstate cg, ref CodeBuilder cdb,elem *e,regm_t *pretregs,uint c
case TYfptr: case TYfptr:
case TYhptr: case TYhptr:
case TYvptr: case TYvptr:
*pretregs |= ALLREGS; pretregs |= ALLREGS;
break; break;
default: default:
break; break;
} }
} }
loaddata(cdb,e,*pretregs); loaddata(cdb,e,pretregs);
break; break;
} }
cssave(e,*pretregs,!OTleaf(op)); cssave(e,pretregs,!OTleaf(op));
L1: L1:
if (!(constflag & 2)) if (!(constflag & 2))
freenode(e); freenode(e);
debug if (debugw) debug if (debugw)
{ {
printf("-codelem(e=%p,*pretregs=%s) %s ",e,regm_str(*pretregs), oper_str(op)); printf("-codelem(e=%p,pretregs=%s) %s ",e,regm_str(pretregs), oper_str(op));
printf("msavereg=%s cg.regcon.cse.mval=%s regcon.cse.mops=%s\n", printf("msavereg=%s cg.regcon.cse.mval=%s regcon.cse.mops=%s\n",
regm_str(cg.msavereg),regm_str(cg.regcon.cse.mval),regm_str(cg.regcon.cse.mops)); regm_str(cg.msavereg),regm_str(cg.regcon.cse.mval),regm_str(cg.regcon.cse.mops));
} }
@ -2742,12 +2748,18 @@ L1:
@trusted @trusted
void scodelem(ref CGstate cg, ref CodeBuilder cdb, elem *e,regm_t *pretregs,regm_t keepmsk,bool constflag) void scodelem(ref CGstate cg, ref CodeBuilder cdb, elem *e,regm_t *pretregs,regm_t keepmsk,bool constflag)
{
scodelem(cg, cdb, e, *pretregs, keepmsk, constflag);
}
@trusted
void scodelem(ref CGstate cg, ref CodeBuilder cdb, elem *e,ref regm_t pretregs,regm_t keepmsk,bool constflag)
{ {
regm_t touse; regm_t touse;
debug if (debugw) debug if (debugw)
printf("+scodelem(e=%p *pretregs=%s keepmsk=%s constflag=%d\n", printf("+scodelem(e=%p *pretregs=%s keepmsk=%s constflag=%d\n",
e,regm_str(*pretregs),regm_str(keepmsk),constflag); e,regm_str(pretregs),regm_str(keepmsk),constflag);
elem_debug(e); elem_debug(e);
if (constflag) if (constflag)
@ -2756,7 +2768,7 @@ void scodelem(ref CGstate cg, ref CodeBuilder cdb, elem *e,regm_t *pretregs,regm
reg_t reg; reg_t reg;
if (isregvar(e, regm, reg) && // if e is a register variable if (isregvar(e, regm, reg) && // if e is a register variable
(regm & *pretregs) == regm && // in one of the right regs (regm & pretregs) == regm && // in one of the right regs
e.Voffset == 0 e.Voffset == 0
) )
{ {
@ -2764,13 +2776,13 @@ void scodelem(ref CGstate cg, ref CodeBuilder cdb, elem *e,regm_t *pretregs,regm
uint sz2 = tysize(e.Vsym.Stype.Tty); uint sz2 = tysize(e.Vsym.Stype.Tty);
if (sz1 <= REGSIZE && sz2 > REGSIZE) if (sz1 <= REGSIZE && sz2 > REGSIZE)
regm &= mLSW | XMMREGS; regm &= mLSW | XMMREGS;
fixresult(cdb,e,regm,*pretregs); fixresult(cdb,e,regm,pretregs);
cssave(e,regm,0); cssave(e,regm,0);
freenode(e); freenode(e);
debug if (debugw) debug if (debugw)
printf("-scodelem(e=%p *pretregs=%s keepmsk=%s constflag=%d\n", printf("-scodelem(e=%p *pretregs=%s keepmsk=%s constflag=%d\n",
e,regm_str(*pretregs),regm_str(keepmsk),constflag); e,regm_str(pretregs),regm_str(keepmsk),constflag);
return; return;
} }
@ -2785,13 +2797,13 @@ void scodelem(ref CGstate cg, ref CodeBuilder cdb, elem *e,regm_t *pretregs,regm
char calledafuncsave = cg.calledafunc; char calledafuncsave = cg.calledafunc;
cg.calledafunc = 0; cg.calledafunc = 0;
CodeBuilder cdbx; cdbx.ctor(); CodeBuilder cdbx; cdbx.ctor();
codelem(cg,cdbx,e,pretregs,constflag); // generate code for the elem codelem(cg,cdbx,e,&pretregs,constflag); // generate code for the elem
regm_t tosave = keepmsk & ~cg.msavereg; /* registers to save */ regm_t tosave = keepmsk & ~cg.msavereg; /* registers to save */
if (tosave) if (tosave)
{ {
cg.stackclean++; cg.stackclean++;
genstackclean(cdbx,cg.stackpush - stackpushsave,*pretregs | cg.msavereg); genstackclean(cdbx,cg.stackpush - stackpushsave,pretregs | cg.msavereg);
cg.stackclean--; cg.stackclean--;
} }
@ -2918,12 +2930,11 @@ void scodelem(ref CGstate cg, ref CodeBuilder cdb, elem *e,regm_t *pretregs,regm
debug if (debugw) debug if (debugw)
printf("-scodelem(e=%p *pretregs=%s keepmsk=%s constflag=%d\n", printf("-scodelem(e=%p *pretregs=%s keepmsk=%s constflag=%d\n",
e,regm_str(*pretregs),regm_str(keepmsk),constflag); e,regm_str(pretregs),regm_str(keepmsk),constflag);
cdb.append(cdbs1); cdb.append(cdbs1);
cdb.append(cdbx); cdb.append(cdbx);
cdb.append(cdbs2); cdb.append(cdbs2);
return;
} }
/********************************************* /*********************************************