Skip to content

Commit

Permalink
more stack offset refactoring
Browse files Browse the repository at this point in the history
  • Loading branch information
WalterBright committed Jan 8, 2013
1 parent 2af1e66 commit 172390e
Show file tree
Hide file tree
Showing 11 changed files with 80 additions and 74 deletions.
4 changes: 1 addition & 3 deletions src/backend/cg.c
Expand Up @@ -25,7 +25,6 @@

#include "fltables.c"

targ_size_t Poffset; /* size of func parameter variables */
targ_size_t framehandleroffset; // offset of C++ frame handler
#if TARGET_OSX
targ_size_t localgotoffset; // offset of where localgot refers to
Expand All @@ -36,8 +35,7 @@ int cseg = CODE; // current code segment
// of the public name index of a COMDAT)

/* Stack offsets */
targ_size_t localsize, /* amt subtracted from SP for local vars */
Poff; // comsubexps, params
targ_size_t localsize; /* amt subtracted from SP for local vars */

/* The following are initialized for the 8088. cod3_set32() or cod3_set64()
* will change them as appropriate.
Expand Down
61 changes: 31 additions & 30 deletions src/backend/cgcod.c
Expand Up @@ -50,9 +50,10 @@ targ_size_t NDPoff; // offset of saved 8087 registers
int BPoff; // offset from BP
int EBPtoESP; // add to EBP offset to get ESP offset
int AllocaOff; // offset of alloca temporary
LocalSection Para; // section of function parameters
LocalSection Auto; // section of automatics and registers
LocalSection Fast; // section of fastpar
targ_size_t EEoffset; // offset of SCstack variables from ESP
LocalSection EEStack; // offset of SCstack variables from ESP

REGSAVE regsave;

Expand Down Expand Up @@ -611,7 +612,7 @@ code *prolog()

/* Compute BP offsets for variables on stack.
* The organization is:
* Poff parameters
* Para.size parameters
* -------- stack is aligned to STACKALIGN
* seg of return addr (if far function)
* IP of return addr
Expand All @@ -630,9 +631,9 @@ code *prolog()
*/

if (tym == TYifunc)
Poff = 26; // how is this number derived?
Para.size = 26; // how is this number derived?
else
Poff = (farfunc ? 3 : 2) * REGSIZE;
Para.size = (farfunc ? 3 : 2) * REGSIZE;

/* The real reason for the FAST section is because the implementation of contracts
* requires a consistent stack frame location for the 'this' pointer. But if varying
Expand Down Expand Up @@ -678,13 +679,13 @@ code *prolog()
// Adjust Auto.size so that it is Auto.alignment byte aligned, assuming that
// before function parameters were pushed the stack was
// Auto.alignment byte aligned
targ_size_t psize = (Poffset + (REGSIZE - 1)) & ~(REGSIZE - 1);
targ_size_t psize = (Para.offset + (REGSIZE - 1)) & ~(REGSIZE - 1);
// if (config.exe == EX_WIN64)
if (STACKALIGN == 16)
// Parameters always consume multiple of 16 bytes
psize = (Poffset + 15) & ~15;
int sz = psize + -Fast.size + -Auto.size + Poff + (needframe ? 0 : REGSIZE);
//printf("Auto.alignment = %d, psize = x%llx, Poff = x%llx, needframe = %d\n", Auto.alignment, psize, Poff, needframe);
psize = (Para.offset + 15) & ~15;
int sz = psize + -Fast.size + -Auto.size + Para.size + (needframe ? 0 : REGSIZE);
//printf("Auto.alignment = %d, psize = x%llx, Para.size = x%llx, needframe = %d\n", Auto.alignment, psize, Para.size, needframe);
if (sz & (Auto.alignment - 1))
{ int adj = Auto.alignment - (sz & (Auto.alignment - 1));
Auto.size -= adj;
Expand All @@ -706,10 +707,10 @@ if (STACKALIGN == 16)
if (!I16 && calledafunc &&
(STACKALIGN == 16 || config.flags4 & CFG4stackalign))
{
//printf("npush = %d Poff = x%x needframe = %d localsize = x%x\n",
// npush, Poff, needframe, localsize);
//printf("npush = %d Para.size = x%x needframe = %d localsize = x%x\n",
// npush, Para.size, needframe, localsize);

int sz = Poff + (needframe ? 0 : -REGSIZE) + localsize + npush * REGSIZE;
int sz = Para.size + (needframe ? 0 : -REGSIZE) + localsize + npush * REGSIZE;
if (STACKALIGN == 16)
{
if (sz & (8|4))
Expand All @@ -719,8 +720,8 @@ if (STACKALIGN == 16)
localsize += 4;
}

//printf("Foff x%02x Auto.size x%02x NDPoff x%02x CSoff x%02x Poff x%02x localsize x%02x\n",
//(int)Foff,(int)Auto.size,(int)NDPoff,(int)CSoff,(int)Poff,(int)localsize);
//printf("Foff x%02x Auto.size x%02x NDPoff x%02x CSoff x%02x Para.size x%02x localsize x%02x\n",
//(int)Foff,(int)Auto.size,(int)NDPoff,(int)CSoff,(int)Para.size,(int)localsize);

xlocalsize = localsize;

Expand Down Expand Up @@ -835,7 +836,7 @@ if (STACKALIGN == 16)
)
{
unsigned spalign = 0;
int sz = Poff + (needframe ? 0 : -REGSIZE) + localsize;
int sz = Para.size + (needframe ? 0 : -REGSIZE) + localsize;
if (STACKALIGN == 16 && (sz & (STACKALIGN - 1)))
spalign = STACKALIGN - (sz & (STACKALIGN - 1));

Expand Down Expand Up @@ -941,10 +942,10 @@ void stackoffsets(int flags)
{
tbl = vec_calloc(globsym.top);
}
Auto.offset = 0; // automatic & register offset
Fast.offset = 0; // SCfastpar offset
Poffset = 0; // parameter offset
EEoffset = 0; // for SCstack's
Para.init(); // parameter offset
Fast.init(); // SCfastpar offset
Auto.init(); // automatic & register offset
EEStack.init(); // for SCstack's
Auto.alignment = REGSIZE;
// for (int pass = 0; pass < 2; pass++)
{
Expand Down Expand Up @@ -1051,27 +1052,27 @@ void stackoffsets(int flags)
break;

case SCstack:
EEoffset = align(sz,EEoffset);
s->Soffset = EEoffset;
//printf("EEoffset = x%lx\n",(long)s->Soffset);
EEoffset += sz;
EEStack.offset = align(sz,EEStack.offset);
s->Soffset = EEStack.offset;
//printf("EEStack.offset = x%lx\n",(long)s->Soffset);
EEStack.offset += sz;
break;

case SCshadowreg:
case SCparameter:
if (config.exe == EX_WIN64)
{
assert((Poffset & 7) == 0);
s->Soffset = Poffset;
Poffset += 8;
assert((Para.offset & 7) == 0);
s->Soffset = Para.offset;
Para.offset += 8;
break;
}
Poffset = align(REGSIZE,Poffset); /* align on word stack boundary */
if (I64 && alignsize == 16 && Poffset & 8)
Poffset += 8;
s->Soffset = Poffset;
Para.offset = align(REGSIZE,Para.offset); /* align on word stack boundary */
if (I64 && alignsize == 16 && Para.offset & 8)
Para.offset += 8;
s->Soffset = Para.offset;
//printf("%s param offset = x%lx, alignsize = %d\n",s->Sident,(long)s->Soffset, (int)alignsize);
Poffset += (s->Sflags & SFLdouble)
Para.offset += (s->Sflags & SFLdouble)
? type_size(tsdouble) // float passed as double
: type_size(s->Stype);
break;
Expand Down
4 changes: 2 additions & 2 deletions src/backend/cgcv.c
@@ -1,5 +1,5 @@
// Copyright (C) 1984-1998 by Symantec
// Copyright (C) 2000-2012 by Digital Mars
// Copyright (C) 2000-2013 by Digital Mars
// All Rights Reserved
// http://www.digitalmars.com
// Written by Walter Bright
Expand Down Expand Up @@ -2328,7 +2328,7 @@ STATIC void cv4_outsym(symbol *s)
s->Sfl = FLreg;
goto case_register;
}
base = Poff - BPoff; // cancel out add of BPoff
base = Para.size - BPoff; // cancel out add of BPoff
goto L1;
case SCauto:
if (s->Sfl == FLreg)
Expand Down
6 changes: 3 additions & 3 deletions src/backend/cod1.c
Expand Up @@ -284,10 +284,10 @@ void genEEcode()
eecontext.EEin++;
regcon.immed.mval = 0;
retregs = 0; //regmask(eecontext.EEelem->Ety);
assert(EEoffset >= REGSIZE);
c = cod3_stackadj(NULL, EEoffset - REGSIZE);
assert(EEStack.offset >= REGSIZE);
c = cod3_stackadj(NULL, EEStack.offset - REGSIZE);
gen1(c,0x50 + SI); // PUSH ESI
genadjesp(c,EEoffset);
genadjesp(c,EEStack.offset);
c = gencodelem(c,eecontext.EEelem,&retregs, FALSE);
assignaddrc(c);
pinholeopt(c,NULL);
Expand Down
38 changes: 19 additions & 19 deletions src/backend/cod3.c
@@ -1,5 +1,5 @@
// Copyright (C) 1984-1998 by Symantec
// Copyright (C) 2000-2012 by Digital Mars
// Copyright (C) 2000-2013 by Digital Mars
// All Rights Reserved
// http://www.digitalmars.com
// Written by Walter Bright
Expand Down Expand Up @@ -2938,7 +2938,7 @@ code* prolog_genvarargs(symbol* sv, regm_t* namedargs)
L2:
MOV 1[RAX],offset_regs // set __va_argsave.offset_regs
MOV 5[RAX],offset_fpregs // set __va_argsave.offset_fpregs
LEA RDX, Poff+Poffset[RBP]
LEA RDX, Para.size+Para.offset[RBP]
MOV 9[RAX],RDX // set __va_argsave.stack_args
SUB RAX,6*8+0x7F // point to start of __va_argsave
MOV 6*8+8*16+4+4+8[RAX],RAX // set __va_argsave.reg_args
Expand Down Expand Up @@ -3009,12 +3009,12 @@ code* prolog_genvarargs(symbol* sv, regm_t* namedargs)
// MOV 5[RAX],offset_fpregs
genc(c,0xC7,modregrm(2,0,AX),FLconst,5,FLconst,offset_fpregs);

// LEA RDX, Poff+Poffset[RBP]
// LEA RDX, Para.size+Para.offset[RBP]
ea = modregrm(2,DX,BPRM);
if (!hasframe)
ea = (modregrm(0,4,SP) << 8) | modregrm(2,DX,4);
Poffset = (Poffset + (REGSIZE - 1)) & ~(REGSIZE - 1);
genc1(c,LEA,(REX_W << 16) | ea,FLconst,Poff + Poffset);
Para.offset = (Para.offset + (REGSIZE - 1)) & ~(REGSIZE - 1);
genc1(c,LEA,(REX_W << 16) | ea,FLconst,Para.size + Para.offset);

// MOV 9[RAX],RDX
genc1(c,0x89,(REX_W << 16) | modregrm(2,DX,AX),FLconst,9);
Expand Down Expand Up @@ -3100,7 +3100,7 @@ code* prolog_loadparams(tym_t tyf, bool pushalloc, regm_t* namedargs)
{
targ_size_t offset = Fast.size + BPoff;
if (s->Sclass == SCshadowreg)
offset = Poff;
offset = Para.size;
offset += s->Soffset;
if (!hasframe)
offset += EBPtoESP;
Expand Down Expand Up @@ -3174,7 +3174,7 @@ code* prolog_loadparams(tym_t tyf, bool pushalloc, regm_t* namedargs)
for (int i = 0; i < sizeof(vregs)/sizeof(vregs[0]); ++i)
{
unsigned preg = vregs[i];
unsigned offset = Poff + i * REGSIZE;
unsigned offset = Para.size + i * REGSIZE;
if (!(shadowregm & (mask[preg] | mask[XMM0 + i])))
{
code *c2;
Expand Down Expand Up @@ -3277,7 +3277,7 @@ code* prolog_loadparams(tym_t tyf, bool pushalloc, regm_t* namedargs)
{
unsigned op = xmmload(s->Stype->Tty); // MOVSS/D xreg,mem
unsigned xreg = s->Sreglsw - XMM0;
code *c2 = genc1(CNIL,op,modregxrm(2,xreg,BPRM),FLconst,Poff + s->Soffset);
code *c2 = genc1(CNIL,op,modregxrm(2,xreg,BPRM),FLconst,Para.size + s->Soffset);
if (!hasframe)
{ // Convert to ESP relative address rather than EBP
c2->Irm = modregxrm(2,xreg,4);
Expand All @@ -3289,7 +3289,7 @@ code* prolog_loadparams(tym_t tyf, bool pushalloc, regm_t* namedargs)
else
{
code *c2 = genc1(CNIL,0x8B ^ (sz == 1),
modregxrm(2,s->Sreglsw,BPRM),FLconst,Poff + s->Soffset);
modregxrm(2,s->Sreglsw,BPRM),FLconst,Para.size + s->Soffset);
if (!I16 && sz == SHORTSIZE)
c2->Iflags |= CFopsize; // operand size
if (I64 && sz >= REGSIZE)
Expand All @@ -3304,7 +3304,7 @@ code* prolog_loadparams(tym_t tyf, bool pushalloc, regm_t* namedargs)
if (sz > REGSIZE)
{
code *c3 = genc1(CNIL,0x8B,
modregxrm(2,s->Sregmsw,BPRM),FLconst,Poff + s->Soffset + REGSIZE);
modregxrm(2,s->Sregmsw,BPRM),FLconst,Para.size + s->Soffset + REGSIZE);
if (I64)
c3->Irex |= REX_W;
if (!hasframe)
Expand Down Expand Up @@ -3522,14 +3522,14 @@ void epilog(block *b)
}
else if (!typfunc(tym) || // if caller cleans the stack
config.exe == EX_WIN64 ||
Poffset == 0) // or nothing pushed on the stack anyway
Para.offset == 0) // or nothing pushed on the stack anyway
{ op++; // to a regular RET
c = gen1(c,op);
}
else
{ // Stack is always aligned on register size boundary
Poffset = (Poffset + (REGSIZE - 1)) & ~(REGSIZE - 1);
c = genc2(c,op,0,Poffset); // RET Poffset
Para.offset = (Para.offset + (REGSIZE - 1)) & ~(REGSIZE - 1);
c = genc2(c,op,0,Para.offset); // RET Para.offset
}
}

Expand Down Expand Up @@ -4065,8 +4065,8 @@ void cod3_adjSymOffsets()
case SCparameter:
case SCregpar:
case SCshadowreg:
//printf("s = '%s', Soffset = x%x, Poff = x%x, EBPtoESP = x%x\n", s->Sident, s->Soffset, Poff, EBPtoESP);
s->Soffset += Poff;
//printf("s = '%s', Soffset = x%x, Para.size = x%x, EBPtoESP = x%x\n", s->Sident, s->Soffset, Para.size, EBPtoESP);
s->Soffset += Para.size;
if (0 && !(funcsym_p->Sfunc->Fflags3 & Fmember))
{
if (!hasframe)
Expand Down Expand Up @@ -4253,7 +4253,7 @@ void assignaddrc(code *c)
case FLstack:
//printf("Soffset = %d, EBPtoESP = %d, base = %d, pointer = %d\n",
//s->Soffset,EBPtoESP,base,c->IEVpointer1);
c->IEVpointer1 += s->Soffset + EBPtoESP - base - EEoffset;
c->IEVpointer1 += s->Soffset + EBPtoESP - base - EEStack.offset;
break;

case FLfast:
Expand Down Expand Up @@ -4317,7 +4317,7 @@ void assignaddrc(code *c)
}
break;
case FLpara:
soff = Poff - BPoff; // cancel out add of BPoff
soff = Para.size - BPoff; // cancel out add of BPoff
goto L1;
case FLfltreg:
c->IEVpointer1 += Foff + BPoff;
Expand Down Expand Up @@ -4415,7 +4415,7 @@ void assignaddrc(code *c)
c->IEVpointer2 += s->Soffset + Auto.size + BPoff;
break;
case FLpara:
c->IEVpointer2 += s->Soffset + Poff;
c->IEVpointer2 += s->Soffset + Para.size;
break;
case FLfltreg:
c->IEVpointer2 += Foff + BPoff;
Expand Down Expand Up @@ -4465,7 +4465,7 @@ targ_size_t cod3_bpoffset(symbol *s)
switch (s->Sfl)
{
case FLpara:
offset += Poff;
offset += Para.size;
break;
case FLfast:
offset += Fast.size + BPoff;
Expand Down
15 changes: 11 additions & 4 deletions src/backend/code.h
Expand Up @@ -133,6 +133,12 @@ struct LocalSection
targ_size_t offset; // offset of section from frame pointer
targ_size_t size; // size of section
int alignment; // alignment size

void init() // initialize
{ offset = 0;
size = 0;
alignment = 0;
}
};

/*******************************
Expand Down Expand Up @@ -174,14 +180,15 @@ extern regm_t FLOATREGS2;
extern regm_t DOUBLEREGS;
extern const char datafl[],stackfl[],segfl[],flinsymtab[];
extern char needframe,usedalloca,gotref;
extern targ_size_t localsize,Poff,
Poffset,funcoffset,
framehandleroffset,
EEoffset;
extern targ_size_t localsize,
funcoffset,
framehandleroffset;
extern segidx_t cseg;
extern int STACKALIGN;
extern LocalSection Para;
extern LocalSection Fast;
extern LocalSection Auto;
extern LocalSection EEStack;
#if TARGET_OSX
extern targ_size_t localgotoffset;
#endif
Expand Down
2 changes: 1 addition & 1 deletion src/backend/cv8.c
Expand Up @@ -532,7 +532,7 @@ void cv8_outsym(Symbol *s)
s->Sfl = FLreg;
goto case_register;
}
base = Poff - BPoff; // cancel out add of BPoff
base = Para.size - BPoff; // cancel out add of BPoff
goto L1;
case SCauto:
if (s->Sfl == FLreg)
Expand Down

0 comments on commit 172390e

Please sign in to comment.