Skip to content

Commit

Permalink
refactor: use LocalSection for alloca data
Browse files Browse the repository at this point in the history
  • Loading branch information
WalterBright committed Sep 15, 2015
1 parent 1ba8636 commit 54898ad
Show file tree
Hide file tree
Showing 7 changed files with 52 additions and 110 deletions.
27 changes: 13 additions & 14 deletions src/backend/cgcod.c
Original file line number Diff line number Diff line change
Expand Up @@ -50,11 +50,11 @@ targ_size_t pushoff; // offset of saved registers
bool pushoffuse; // using pushoff
int BPoff; // offset from BP
int EBPtoESP; // add to EBP offset to get ESP offset
targ_size_t AllocaOff; // offset of alloca temporary
LocalSection Para; // section of function parameters
LocalSection Auto; // section of automatics and registers
LocalSection Fast; // section of fastpar
LocalSection EEStack; // offset of SCstack variables from ESP
LocalSection Alloca; // data for alloca() temporary

REGSAVE regsave;

Expand All @@ -81,7 +81,6 @@ bool anyiasm; // !=0 if any inline assembler
char calledafunc; // !=0 if we called a function
char needframe; // if TRUE, then we will need the frame
// pointer (BP for the 8088)
char usedalloca; // if TRUE, then alloca() was called
char gotref; // !=0 if the GOTsym was referenced
unsigned usednteh; // if !=0, then used NT exception handling

Expand Down Expand Up @@ -159,7 +158,6 @@ void codgen()

// if no parameters, assume we don't need a stack frame
needframe = 0;
usedalloca = 0;
gotref = 0;
stackchanged = 0;
stackpush = 0;
Expand All @@ -169,6 +167,7 @@ void codgen()
cgstate.stackclean = 1;
retsym = NULL;

Alloca.init();
regsave.reset();
#if TX86
memset(_8087elems,0,sizeof(_8087elems));
Expand Down Expand Up @@ -686,7 +685,7 @@ code *prolog()
* Auto.size autos and regs
* regsave.off any saved registers
* Foff floating register
* AllocaOff alloca temporary
* Alloca.size alloca temporary
* CSoff common subs
* NDPoff any 8087 saved registers
* monitor context record
Expand Down Expand Up @@ -763,10 +762,10 @@ code *prolog()
else
Foff = regsave.off;

assert(usedalloca != 1);
AllocaOff = alignsection(usedalloca ? (Foff - REGSIZE) : Foff, REGSIZE, bias);
Alloca.alignment = REGSIZE;
Alloca.offset = alignsection(Foff - Alloca.size, Alloca.alignment, bias);

CSoff = alignsection(AllocaOff - cstop * REGSIZE, REGSIZE, bias);
CSoff = alignsection(Alloca.offset - cstop * REGSIZE, REGSIZE, bias);

#if TX86
NDPoff = alignsection(CSoff - NDP::savetop * NDPSAVESIZE, REGSIZE, bias);
Expand Down Expand Up @@ -796,8 +795,8 @@ code *prolog()

localsize = -pushoff;

//printf("AllocaOff = x%llx, cstop = x%llx, CSoff = x%llx, NDPoff = x%llx, localsize = x%llx\n",
//(long long)AllocaOff, (long long)cstop, (long long)CSoff, (long long)NDPoff, (long long)localsize);
//printf("Alloca.offset = x%llx, cstop = x%llx, CSoff = x%llx, NDPoff = x%llx, localsize = x%llx\n",
//(long long)Alloca.offset, (long long)cstop, (long long)CSoff, (long long)NDPoff, (long long)localsize);
assert((targ_ptrdiff_t)localsize >= 0);

// Keep the stack aligned by 8 for any subsequent function calls
Expand Down Expand Up @@ -855,7 +854,7 @@ code *prolog()
xlocalsize >= 0x1000 ||
(usednteh & ~NTEHjmonitor) ||
anyiasm ||
usedalloca
Alloca.size
)
needframe = 1;
}
Expand Down Expand Up @@ -889,19 +888,19 @@ code *prolog()
if (config.flags & CFGstack) // if stack overflow check
{
cstackadj = prolog_frameadj(tyf, xlocalsize, enter, &pushalloc);
if (usedalloca)
if (Alloca.size)
cstackadj = cat(cstackadj, prolog_setupalloca());
}
else if (needframe) /* if variables or parameters */
{
if (xlocalsize) /* if any stack offset */
{
cstackadj = prolog_frameadj(tyf, xlocalsize, enter, &pushalloc);
if (usedalloca)
if (Alloca.size)
cstackadj = cat(cstackadj, prolog_setupalloca());
}
else
assert(usedalloca == 0);
assert(Alloca.size == 0);
}
else if (xlocalsize)
{
Expand All @@ -910,7 +909,7 @@ code *prolog()
BPoff += REGSIZE;
}
else
assert((localsize | usedalloca) == 0 || (usednteh & NTEHjmonitor));
assert((localsize | Alloca.size) == 0 || (usednteh & NTEHjmonitor));
EBPtoESP += xlocalsize;
c = cat(c, cstackadj);
}
Expand Down
71 changes: 5 additions & 66 deletions src/backend/cod1.c
Original file line number Diff line number Diff line change
Expand Up @@ -801,34 +801,6 @@ code *getlvalue(code *pcs,elem *e,regm_t keepmsk)
c = CNIL;
switch (fl)
{
#if 0 && TARGET_LINUX
case FLgot:
case FLgotoff:
gotref = 1;
pcs->IEVsym1 = s;
pcs->IEVoffset1 = e->EV.sp.Voffset;
if (e->Eoper == OPvar && fl == FLgot)
{
code *c1;
unsigned saveop = pcs->Iop;
idxregs = allregs & ~keepmsk; // get a scratch register
c = allocreg(&idxregs,&reg,TYptr);
pcs->Irm = modregrm(2,reg,BX); // BX has GOT
pcs->Isib = 0;
//pcs->Iflags |= CFvolatile;
pcs->Iop = 0x8B;
c = gen(c,pcs); // MOV reg,disp[EBX]
pcs->Irm = modregrm(0,0,reg);
pcs->IEVoffset1 = 0;
pcs->Iop = saveop;
}
else
{
pcs->Irm = modregrm(2,0,BX); // disp[EBX] is addr
pcs->Isib = 0;
}
break;
#endif
case FLoper:
#ifdef DEBUG
if (debugw) printf("getlvalue(e = %p, keepmsk = %s)\n", e, regm_str(keepmsk));
Expand Down Expand Up @@ -868,9 +840,7 @@ code *getlvalue(code *pcs,elem *e,regm_t keepmsk)
f = FLconst;
if (e1isadd &&
((e12->Eoper == OPrelconst
#if TARGET_SEGMENTED
&& (f = el_fl(e12)) != FLfardata
#endif
) ||
(e12->Eoper == OPconst && !I16 && !e1->Ecount && (!I64 || el_signx32(e12)))) &&
!(I64 && (config.flags3 & CFG3pic || config.exe == EX_WIN64)) &&
Expand Down Expand Up @@ -917,9 +887,6 @@ code *getlvalue(code *pcs,elem *e,regm_t keepmsk)
{
regm_t scratchm;

#if 0 && TARGET_LINUX
assert(f != FLgot && f != FLgotoff);
#endif
char ssflags = ssindex_array[ssi].ssflags;
if (ssflags & SSFLnobp && stackfl[f])
goto L6;
Expand Down Expand Up @@ -998,21 +965,6 @@ code *getlvalue(code *pcs,elem *e,regm_t keepmsk)
/* Load index register with result of e11 */
c = scodelem(e11,&idxregs,keepmsk,TRUE);
setaddrmode(pcs, idxregs);
#if 0 && TARGET_LINUX
if (e12->EV.sp.Vsym->Sfl == FLgot || e12->EV.sp.Vsym->Sfl == FLgotoff)
{
gotref = 1;
#if 1
reg = findreg(idxregs & (ALLREGS | mBP));
pcs->Irm = modregrm(2,0,4);
pcs->Isib = modregrm(0,reg,BX);
#else
pcs->Isib = modregrm(0,pcs->Irm,BX);
pcs->Irm = modregrm(2,0,4);
#endif
}
else
#endif
if (stackfl[f]) /* if we need [EBP] too */
{ unsigned idx = pcs->Irm & 7;
if (pcs->Irex & REX_B)
Expand All @@ -1026,9 +978,6 @@ code *getlvalue(code *pcs,elem *e,regm_t keepmsk)
{
idxregs = IDXREGS & ~keepmsk; /* only these can be index regs */
assert(idxregs);
#if 0 && TARGET_LINUX
assert(f != FLgot && f != FLgotoff);
#endif
if (stackfl[f]) /* if stack data type */
{ idxregs &= mSI | mDI; /* BX can't index off stack */
if (!idxregs) goto L1; /* index regs aren't avail */
Expand Down Expand Up @@ -1363,12 +1312,10 @@ code *getlvalue(code *pcs,elem *e,regm_t keepmsk)
goto L3;
case FLdata:
case FLudata:
#if TARGET_SEGMENTED
case FLcsdata:
#endif
#if TARGET_LINUX || TARGET_OSX || TARGET_FREEBSD || TARGET_OPENBSD || TARGET_SOLARIS
case FLgot:
case FLgotoff:
#if TARGET_LINUX || TARGET_OSX || TARGET_FREEBSD || TARGET_OPENBSD || TARGET_SOLARIS
case FLtlsdata:
#endif
L3:
Expand Down Expand Up @@ -1416,14 +1363,12 @@ code *getlvalue(code *pcs,elem *e,regm_t keepmsk)
pcs->Iflags |= CFcs | CFoff;
}
#endif
#if TARGET_LINUX || TARGET_OSX || TARGET_FREEBSD || TARGET_OPENBSD || TARGET_SOLARIS
if (I64 && config.flags3 & CFG3pic &&
(fl == FLtlsdata || s->ty() & mTYthread))
{
pcs->Iflags |= CFopsize;
pcs->Irex = 0x48;
}
#endif
pcs->IEVsym1 = s;
pcs->IEVoffset1 = e->EV.sp.Voffset;
if (sz == 1)
Expand Down Expand Up @@ -1453,9 +1398,7 @@ code *getlvalue(code *pcs,elem *e,regm_t keepmsk)
break;
}
#endif
#if TARGET_SEGMENTED
case FLfardata:
#endif
case FLfunc: /* reading from code seg */
if (config.exe & EX_flat)
goto L3;
Expand Down Expand Up @@ -3273,7 +3216,6 @@ STATIC code * funccall(elem *e,unsigned numpara,unsigned numalign,regm_t *pretre
c1 = getregs(~s->Sregsaved & (mBP | ALLREGS | mES | XMMREGS));
if (strcmp(s->Sident,"alloca") == 0)
{
#if 1
s = getRtlsym(RTLSYM_ALLOCA);
makeitextern(s);
int areg = CX;
Expand All @@ -3283,10 +3225,7 @@ STATIC code * funccall(elem *e,unsigned numpara,unsigned numalign,regm_t *pretre
c1 = genc(c1,0x8D,modregrm(2,areg,BPRM),FLallocatmp,0,0,0); // LEA areg,&localsize[BP]
if (I64)
code_orrex(c1, REX_W);
usedalloca = 2; // new way
#else
usedalloca = 1; // old way
#endif
Alloca.size = REGSIZE;
}
if (sytab[s->Sclass] & SCSS) // if function is on stack (!)
{
Expand Down Expand Up @@ -4488,11 +4427,11 @@ code *loaddata(elem *e,regm_t *pretregs)
// See if we can use register that parameter was passed in
if (regcon.params &&
(e->EV.sp.Vsym->Sclass == SCfastpar || e->EV.sp.Vsym->Sclass == SCshadowreg) &&
regcon.params & mask[e->EV.sp.Vsym->Spreg] &&
!(e->Eoper == OPvar && e->EV.sp.Voffset > 0) && // Must be at the base of that variable
(regcon.params & mask[e->EV.sp.Vsym->Spreg] && e->EV.sp.Voffset == 0 ||
regcon.params & mask[e->EV.sp.Vsym->Spreg2] && e->EV.sp.Voffset == REGSIZE) &&
sz <= REGSIZE) // make sure no 'paint' to a larger size happened
{
reg = e->EV.sp.Vsym->Spreg;
reg = e->EV.sp.Voffset ? e->EV.sp.Vsym->Spreg2 : e->EV.sp.Vsym->Spreg;
forregs = mask[reg];
#ifdef DEBUG
if (debugr)
Expand Down
29 changes: 10 additions & 19 deletions src/backend/cod3.c
Original file line number Diff line number Diff line change
Expand Up @@ -2140,7 +2140,7 @@ regm_t cod3_useBP()
config.flags & CFGstack ||
localsize >= 0x100 || // arbitrary value < 0x1000
(usednteh & ~NTEHjmonitor) ||
usedalloca
Alloca.size
)
goto Lcant;
}
Expand Down Expand Up @@ -2874,13 +2874,6 @@ code* prolog_ifunc2(tym_t tyf, tym_t tym, bool pushds)

code* prolog_16bit_windows_farfunc(tym_t* tyf, bool* pushds)
{
#if SCPP
// alloca() can't be because the 'special' parameter won't be at
// a known offset from BP.
if (usedalloca == 1)
synerr(EM_alloca_win); // alloca() can't be in Windows functions
#endif

int wflags = config.wflags;
if (wflags & WFreduced && !(*tyf & mTYexport))
{ // reduced prolog/epilog for non-exported functions
Expand Down Expand Up @@ -3104,7 +3097,7 @@ code* prolog_setupalloca()
// Set up magic parameter for alloca()
// MOV -REGSIZE[BP],localsize - BPoff
code* c = genc(NULL,0xC7,modregrm(2,0,BPRM),
FLconst,AllocaOff + BPoff,
FLconst,Alloca.offset + BPoff,
FLconst,localsize - BPoff);
if (I64)
code_orrex(c, REX_W);
Expand Down Expand Up @@ -3857,7 +3850,7 @@ void epilog(block *b)
goto L4;
}

if (localsize | usedalloca)
if (localsize)
{
c = genc1(c,LEA,modregrm(1,SP,6),FLconst,(targ_uns)-2); /* LEA SP,-2[BP] */
}
Expand All @@ -3877,7 +3870,7 @@ void epilog(block *b)
{
L4:
assert(hasframe);
if (xlocalsize | usedalloca)
if (xlocalsize)
{
if (config.flags2 & CFG2stomp)
{ /* MOV ECX,0xBEAF
Expand Down Expand Up @@ -3919,7 +3912,7 @@ void epilog(block *b)
!(config.target_cpu >= TARGET_80386 && config.flags4 & CFG4speed)
)
c = gen1(c,0xC9); // LEAVE
else if (0 && xlocalsize == REGSIZE && !usedalloca && I32)
else if (0 && xlocalsize == REGSIZE && Alloca.size == 0 && I32)
{ // This doesn't work - I should figure out why
mfuncreg &= ~mask[regx];
c = gen1(c,0x58 + regx); // POP regx
Expand Down Expand Up @@ -4758,7 +4751,7 @@ void assignaddrc(code *c)
c->Iflags |= CFunambig;
goto L2;
case FLallocatmp:
c->IEVpointer1 += AllocaOff + BPoff;
c->IEVpointer1 += Alloca.offset + BPoff;
goto L2;
case FLbprel:
c->IEVpointer1 += s->Soffset;
Expand Down Expand Up @@ -4865,7 +4858,7 @@ void assignaddrc(code *c)
c->IEVpointer2 += Foff + BPoff;
break;
case FLallocatmp:
c->IEVpointer2 += AllocaOff + BPoff;
c->IEVpointer2 += Alloca.offset + BPoff;
break;
case FLbprel:
c->IEVpointer2 += s->Soffset;
Expand Down Expand Up @@ -6578,13 +6571,11 @@ static void do32bit(MiniCodeBuf *pbuf, enum FL fl,union evc *uev,int flags, int
ad = * (targ_size_t *) uev + pbuf->getOffset();
objmod->reftocodeseg(cseg,pbuf->offset,ad);
break;
#if TARGET_SEGMENTED

case FLcsdata:
case FLfardata:
#if DEBUG
symbol_print(uev->sp.Vsym);
#endif
#endif
//symbol_print(uev->sp.Vsym);

// NOTE: In ELFOBJ all symbol refs have been tagged FLextern
// strings and statics are treated like offsets from a
// un-named external with is the start of .rodata or .data
Expand Down
2 changes: 1 addition & 1 deletion src/backend/cod5.c
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ void cod5_prol_epi()

if (!(config.flags4 & CFG4optimized) ||
anyiasm ||
usedalloca ||
Alloca.size ||
usednteh ||
tyf & (mTYnaked | mTYloadds) ||
tym == TYifunc ||
Expand Down
Loading

0 comments on commit 54898ad

Please sign in to comment.