use genpush() more aggressively

This commit is contained in:
Walter Bright 2024-06-27 11:44:16 -07:00 committed by The Dlang Bot
parent 9359512214
commit 3b175924ba
4 changed files with 36 additions and 45 deletions

View file

@ -174,7 +174,8 @@ struct CGstate
targ_size_t NDPoff; // offset of saved 8087 registers
targ_size_t pushoff; // offset of saved registers
bool pushoffuse; // using pushoff
bool pushoffuse; // save/restore registers using pushoff rather than PUSH/POP
char needframe; // if true, then we will need the frame
// pointer (BP for the 8088)

View file

@ -314,7 +314,7 @@ void genEEcode()
regm_t retregs = 0; //regmask(eecontext.EEelem.Ety);
assert(cgstate.EEStack.offset >= REGSIZE);
cod3_stackadj(cdb, cast(int)(cgstate.EEStack.offset - REGSIZE));
cdb.gen1(0x50 + SI); // PUSH ESI
cdb.genpush(SI); // PUSH ESI
cdb.genadjesp(cast(int)cgstate.EEStack.offset);
gencodelem(cdb, eecontext.EEelem, &retregs, false);
code *c = cdb.finish();
@ -373,12 +373,8 @@ uint gensaverestore(regm_t regm,ref CodeBuilder cdbsave,ref CodeBuilder cdbresto
else
{
stackused += REGSIZE;
cdbsave.gen1(0x50 + (i & 7)); // PUSH i
cdb.gen1(0x58 + (i & 7)); // POP i
if (i & 8)
{ code_orrex(cdbsave.last(), REX_B);
code_orrex(cdb.last(), REX_B);
}
cdbsave.genpush(i); // PUSH i
cdb.genpop(i); // POP i
}
restore[i] = cdb.finish();
}
@ -434,7 +430,7 @@ void genstackclean(ref CodeBuilder cdb,uint numpara,regm_t keepmsk)
if (scratchm)
{
const r = allocreg(cdb, scratchm, TYint);
cdb.gen1(0x58 + r); // POP r
cdb.genpop(r); // POP r
}
else
cod3_stackadj(cdb, -numpara);
@ -4838,7 +4834,7 @@ void pushParams(ref CodeBuilder cdb, elem* e, uint stackalign, tym_t tyf)
{
reg_t reg;
if (reghasvalue(cgstate.allregs, value, reg))
cdb.gen1(0x50 + reg); // PUSH reg
cdb.genpush(reg); // PUSH reg
else
cdb.genc2(0x68,0,value); // PUSH value
value = e.Vulong4[i ^ 1]; // treat Vldouble as 2 element array of 32 bit uint

View file

@ -4827,9 +4827,7 @@ void getoffset(ref CGstate cg, ref CodeBuilder cdb,elem *e,reg_t reg)
if (stack)
{
cdb.gen1(0x50 + (reg & 7)); // PUSH reg
if (reg & 8)
code_orrex(cdb.last(), REX_B);
cdb.genpush(reg); // PUSH reg
cdb.genadjesp(REGSIZE);
cgstate.stackchanged = 1;
}
@ -4927,9 +4925,7 @@ void getoffset(ref CGstate cg, ref CodeBuilder cdb,elem *e,reg_t reg)
loadea(cdb,e,cs,LEA,reg,0,0,0); // LEA reg,EA
if (I64)
code_orrex(cdb.last(), REX_W);
cdb.gen1(0x50 + (reg & 7)); // PUSH reg
if (reg & 8)
code_orrex(cdb.last(), REX_B);
cdb.genpush(reg); // PUSH reg
cdb.genadjesp(REGSIZE);
cgstate.stackchanged = 1;
}

View file

@ -1851,7 +1851,7 @@ else
const r1 = allocreg(cdb,scratchm,TYint);
cdb.genc2(CALL,0,0); // CALL L1
cdb.gen1(0x58 + r1); // L1: POP R1
cdb.genpop(r1); // L1: POP R1
cdb.genc1(0x03,modregrm(2,r1,4),FLswitch,0); // ADD R1,disp[reg*4][EBX]
cdb.last().IEV1.Vswitch = b;
cdb.last().Isib = modregrm(2,reg,r1);
@ -1927,7 +1927,7 @@ else
{ // Add in GOT
getregs(cdb,mDX);
cdb.genc2(CALL,0,0); // CALL L1
cdb.gen1(0x58 + DI); // L1: POP EDI
cdb.genpop(DI); // L1: POP EDI
// ADD EDI,_GLOBAL_OFFSET_TABLE_+3
Symbol *gotsym = Obj.getGOTsym();
@ -2409,8 +2409,8 @@ void cod3_ptrchk(ref CodeBuilder cdb,ref code pcs,regm_t keepmsk)
pop = 0x07;
}
else
{ push = 0x50 + i;
pop = push | 8;
{ push = 0x50 | i;
pop = 0x58 | i;
}
cdb.gen1(push); // PUSH i
cs2 = cat(gen1(null,pop),cs2); // POP i
@ -2444,7 +2444,7 @@ void cod3_ptrchk(ref CodeBuilder cdb,ref code pcs,regm_t keepmsk)
cdb.gen1(segreg); // PUSH segreg
}
cdb.gen1(0x50 + reg); // PUSH reg
cdb.genpush(reg); // PUSH reg
// Rewrite the addressing mode in *pcs so it is just 0[reg]
setaddrmode(pcs, idxregs);
@ -2678,7 +2678,7 @@ void cdgot(ref CGstate cg, ref CodeBuilder cdb, elem *e, regm_t *pretregs)
const reg = allocreg(cdb,retregs, TYnptr);
cdb.genc(CALL,0,0,0,FLgot,0); // CALL L1
cdb.gen1(0x58 + reg); // L1: POP reg
cdb.genpop(reg); // L1: POP reg
fixresult(cdb,e,retregs,*pretregs);
}
@ -2690,7 +2690,7 @@ void cdgot(ref CGstate cg, ref CodeBuilder cdb, elem *e, regm_t *pretregs)
const reg = allocreg(cdb,retregs, TYnptr);
cdb.genc2(CALL,0,0); // CALL L1
cdb.gen1(0x58 + reg); // L1: POP reg
cdb.genpop(reg); // L1: POP reg
// ADD reg,_GLOBAL_OFFSET_TABLE_+3
Symbol *gotsym = Obj.getGOTsym();
@ -3348,8 +3348,8 @@ void prolog_16bit_windows_farfunc(ref CodeBuilder cdb, tym_t* tyf, bool* pushds)
}
if (wflags & WFincbp)
cdb.gen1(0x40 + BP); // INC BP
cdb.gen1(0x50 + BP); // PUSH BP
genregs(cdb,0x8B,BP,SP); // MOV BP,SP
cdb.genpush(BP); // PUSH BP
genregs(cdb,0x8B,BP,SP); // MOV BP,SP
if (wflags & (WFsaveds | WFds | WFss | WFdgroup))
{
cdb.gen1(0x1E); // PUSH DS
@ -3381,7 +3381,7 @@ void prolog_frame(ref CodeBuilder cdb, bool farfunc, ref uint xlocalsize, out bo
{
// PUSH RBP
// LEA RBP,0[RSP]
cdb. gen1(0x50 + BP);
cdb.genpush(BP);
cdb.genc1(LEA,(REX_W<<16) | (modregrm(0,4,SP)<<8) | modregrm(2,BP,4),FLconst,0);
enter = false;
return;
@ -3401,7 +3401,7 @@ void prolog_frame(ref CodeBuilder cdb, bool farfunc, ref uint xlocalsize, out bo
config.flags4 & CFG4speed)
)
{
cdb.gen1(0x50 + BP); // PUSH BP
cdb.genpush(BP); // PUSH BP
genregs(cdb,0x8B,BP,SP); // MOV BP,SP
if (I64)
code_orrex(cdb.last(), REX_W); // MOV RBP,RSP
@ -3460,7 +3460,7 @@ void prolog_stackalign(ref CodeBuilder cdb)
@trusted
void prolog_frameadj(ref CodeBuilder cdb, tym_t tyf, uint xlocalsize, bool enter, bool* pushalloc)
{
uint pushallocreg = (tyf == TYmfunc) ? CX : AX;
reg_t pushallocreg = (tyf == TYmfunc) ? CX : AX;
bool check;
if (config.exe & (EX_LINUX | EX_LINUX64))
@ -3519,7 +3519,7 @@ void prolog_frameadj(ref CodeBuilder cdb, tym_t tyf, uint xlocalsize, bool enter
}
else if (xlocalsize == REGSIZE && config.flags4 & CFG4optimized)
{
cdb. gen1(0x50 + pushallocreg); // PUSH AX
cdb.genpush(pushallocreg); // PUSH AX
// Do this to prevent an -x[EBP] to be moved in
// front of the push.
code_orflag(cdb.last(),CFvolatile);
@ -3532,16 +3532,16 @@ void prolog_frameadj(ref CodeBuilder cdb, tym_t tyf, uint xlocalsize, bool enter
void prolog_frameadj2(ref CodeBuilder cdb, tym_t tyf, uint xlocalsize, bool* pushalloc)
{
uint pushallocreg = (tyf == TYmfunc) ? CX : AX;
reg_t pushallocreg = (tyf == TYmfunc) ? CX : AX;
if (xlocalsize == REGSIZE)
{
cdb.gen1(0x50 + pushallocreg); // PUSH AX
cdb.genpush(pushallocreg); // PUSH AX
*pushalloc = true;
}
else if (xlocalsize == 2 * REGSIZE)
{
cdb.gen1(0x50 + pushallocreg); // PUSH AX
cdb.gen1(0x50 + pushallocreg); // PUSH AX
cdb.genpush(pushallocreg); // PUSH AX
cdb.genpush(pushallocreg); // PUSH AX
*pushalloc = true;
}
else
@ -3744,9 +3744,7 @@ private void epilog_restoreregs(ref CodeBuilder cdb, regm_t topop)
}
else
{
cdb.gen1(0x58 + (reg & 7)); // POP reg
if (reg & 8)
code_orrex(cdb.last(), REX_B);
cdb.genpop(reg); // POP reg
}
topop &= ~regm;
}
@ -4397,7 +4395,7 @@ void epilog(block *b)
cpopds.Iop = NOP; // don't need previous one
cdbx.gen1(0x1F); // POP DS
}
cdbx.gen1(0x58 + BP); // POP BP
cdbx.genpop(BP); // POP BP
if (config.wflags & WFincbp)
cdbx.gen1(0x48 + BP); // DEC BP
assert(cgstate.hasframe);
@ -4440,13 +4438,13 @@ void epilog(block *b)
genjmp(cdbx,JNE,FLcode,cast(block *)c1); // JNE L1
// explicitly mark as short jump, needed for correct retsize calculation (Bugzilla 15779)
cdbx.last().Iflags &= ~CFjmp16;
cdbx.gen1(0x58 + BP); // POP BP
cdbx.genpop(BP); // POP BP
}
else if (config.exe == EX_WIN64)
{ // See https://msdn.microsoft.com/en-us/library/tawsa7cb%28v=vs.100%29.aspx
// LEA RSP,0[RBP]
cdbx.genc1(LEA,(REX_W<<16)|modregrm(2,SP,BPRM),FLconst,0);
cdbx.gen1(0x58 + BP); // POP RBP
cdbx.genpop(BP); // POP RBP
}
else if (config.target_cpu >= TARGET_80286 &&
!(config.target_cpu >= TARGET_80386 && config.flags4 & CFG4speed)
@ -4455,26 +4453,26 @@ void epilog(block *b)
else if (0 && xlocalsize == REGSIZE && cgstate.Alloca.size == 0 && I32)
{ // This doesn't work - I should figure out why
cgstate.mfuncreg &= ~mask(regx);
cdbx.gen1(0x58 + regx); // POP regx
cdbx.gen1(0x58 + BP); // POP BP
cdbx.genpop(regx); // POP regx
cdbx.genpop(BP); // POP BP
}
else
{
genregs(cdbx,0x8B,SP,BP); // MOV SP,BP
if (I64)
code_orrex(cdbx.last(), REX_W); // MOV RSP,RBP
cdbx.gen1(0x58 + BP); // POP BP
cdbx.genpop(BP); // POP BP
}
}
else
cdbx.gen1(0x58 + BP); // POP BP
cdbx.genpop(BP); // POP BP
if (config.wflags & WFincbp && farfunc)
cdbx.gen1(0x48 + BP); // DEC BP
}
else if (xlocalsize == REGSIZE && (!I16 || b.BC == BCret))
{
cgstate.mfuncreg &= ~mask(regx);
cdbx.gen1(0x58 + regx); // POP regx
cdbx.genpop(regx); // POP regx
}
else if (xlocalsize)
cod3_stackadj(cdbx, cast(int)-xlocalsize);
@ -4504,7 +4502,7 @@ Lret:
ADD ESP, Para.offset
JMP REG
*/
cdbx.gen1(0x58+regx);
cdbx.genpop(regx);
cdbx.genc2(0x81, modregrm(3,0,SP), cgstate.Para.offset);
if (I64)
code_orrex(cdbx.last(), REX_W);