From 172390e38e3e086d5c3e00c3b7a4573ac162116b Mon Sep 17 00:00:00 2001 From: Walter Bright Date: Tue, 8 Jan 2013 02:35:21 -0800 Subject: [PATCH] more stack offset refactoring --- src/backend/cg.c | 4 +-- src/backend/cgcod.c | 61 +++++++++++++++++++++++---------------------- src/backend/cgcv.c | 4 +-- src/backend/cod1.c | 6 ++--- src/backend/cod3.c | 38 ++++++++++++++-------------- src/backend/code.h | 15 ++++++++--- src/backend/cv8.c | 2 +- src/backend/dwarf.c | 18 ++++++------- src/backend/el.c | 2 +- src/backend/out.c | 2 +- src/glue.c | 2 +- 11 files changed, 80 insertions(+), 74 deletions(-) diff --git a/src/backend/cg.c b/src/backend/cg.c index 5f8984ab4407..abc3b8cecade 100644 --- a/src/backend/cg.c +++ b/src/backend/cg.c @@ -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 @@ -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. diff --git a/src/backend/cgcod.c b/src/backend/cgcod.c index f20903871a4d..1d012e269601 100644 --- a/src/backend/cgcod.c +++ b/src/backend/cgcod.c @@ -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; @@ -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 @@ -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 @@ -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; @@ -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)) @@ -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; @@ -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)); @@ -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++) { @@ -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; diff --git a/src/backend/cgcv.c b/src/backend/cgcv.c index f9d6ae9e6589..2a44765d9d30 100644 --- a/src/backend/cgcv.c +++ b/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 @@ -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) diff --git a/src/backend/cod1.c b/src/backend/cod1.c index b4e764587b26..8c1eb0549431 100644 --- a/src/backend/cod1.c +++ b/src/backend/cod1.c @@ -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); diff --git a/src/backend/cod3.c b/src/backend/cod3.c index 4897bab1f462..f6ecfaeac1f5 100644 --- a/src/backend/cod3.c +++ b/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 @@ -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 @@ -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); @@ -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; @@ -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; @@ -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); @@ -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) @@ -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) @@ -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 } } @@ -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) @@ -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: @@ -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; @@ -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; @@ -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; diff --git a/src/backend/code.h b/src/backend/code.h index a15db5e50665..ad936ad26b8e 100644 --- a/src/backend/code.h +++ b/src/backend/code.h @@ -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; + } }; /******************************* @@ -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 diff --git a/src/backend/cv8.c b/src/backend/cv8.c index 6ba4525e1801..d1c3073798c9 100644 --- a/src/backend/cv8.c +++ b/src/backend/cv8.c @@ -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) diff --git a/src/backend/dwarf.c b/src/backend/dwarf.c index d29647aa21c8..2849fffc27f0 100644 --- a/src/backend/dwarf.c +++ b/src/backend/dwarf.c @@ -1,5 +1,5 @@ -// Copyright (c) 1999-2011 by Digital Mars +// Copyright (c) 1999-2013 by Digital Mars // All Rights Reserved // written by Walter Bright // http://www.digitalmars.com @@ -1250,11 +1250,11 @@ void dwarf_func_term(Symbol *sfunc) sa->Sclass == SCparameter) infobuf->writesLEB128(sa->Soffset); else if (sa->Sclass == SCfastpar) - infobuf->writesLEB128(Fast.size + BPoff - Poff + sa->Soffset); + infobuf->writesLEB128(Fast.size + BPoff - Para.size + sa->Soffset); else if (sa->Sclass == SCbprel) - infobuf->writesLEB128(-Poff + sa->Soffset); + infobuf->writesLEB128(-Para.size + sa->Soffset); else - infobuf->writesLEB128(Auto.size + BPoff - Poff + sa->Soffset); + infobuf->writesLEB128(Auto.size + BPoff - Para.size + sa->Soffset); } infobuf->buf[soffset] = infobuf->size() - soffset - 1; break; @@ -1298,8 +1298,8 @@ void dwarf_func_term(Symbol *sfunc) /* ============= debug_loc =========================== */ - assert(Poff >= 2 * REGSIZE); - assert(Poff < 63); // avoid sLEB128 encoding + assert(Para.size >= 2 * REGSIZE); + assert(Para.size < 63); // avoid sLEB128 encoding unsigned short op_size = 0x0002; unsigned short loc_op; @@ -1308,21 +1308,21 @@ void dwarf_func_term(Symbol *sfunc) dwarf_appreladdr(debug_loc_seg, debug_loc_buf, seg, funcoffset + 0); dwarf_appreladdr(debug_loc_seg, debug_loc_buf, seg, funcoffset + 1); - loc_op = ((Poff - REGSIZE) << 8) | (DW_OP_breg0 + dwarf_regno(SP)); + loc_op = ((Para.size - REGSIZE) << 8) | (DW_OP_breg0 + dwarf_regno(SP)); debug_loc_buf->write32(loc_op << 16 | op_size); // after push EBP dwarf_appreladdr(debug_loc_seg, debug_loc_buf, seg, funcoffset + 1); dwarf_appreladdr(debug_loc_seg, debug_loc_buf, seg, funcoffset + 3); - loc_op = ((Poff) << 8) | (DW_OP_breg0 + dwarf_regno(SP)); + loc_op = ((Para.size) << 8) | (DW_OP_breg0 + dwarf_regno(SP)); debug_loc_buf->write32(loc_op << 16 | op_size); // after mov EBP, ESP dwarf_appreladdr(debug_loc_seg, debug_loc_buf, seg, funcoffset + 3); dwarf_appreladdr(debug_loc_seg, debug_loc_buf, seg, funcoffset + sfunc->Ssize); - loc_op = ((Poff) << 8) | (DW_OP_breg0 + dwarf_regno(BP)); + loc_op = ((Para.size) << 8) | (DW_OP_breg0 + dwarf_regno(BP)); debug_loc_buf->write32(loc_op << 16 | op_size); // 2 zero addresses to end loc_list diff --git a/src/backend/el.c b/src/backend/el.c index 226ec0cb232d..47292c0b87f0 100644 --- a/src/backend/el.c +++ b/src/backend/el.c @@ -1129,7 +1129,7 @@ symbol *el_alloc_localgot() sprintf(name, "_LOCALGOT%d", tmpnum++); localgot = symbol_name(name, SCauto, type_fake(TYnptr)); symbol_add(localgot); - localgot->Sfl = FLauto; // can't be FLauto yet, executables crash for unknown reasons + localgot->Sfl = FLauto; localgot->Sflags = SFLfree | SFLunambig | GTregcand; } return localgot; diff --git a/src/backend/out.c b/src/backend/out.c index 345837d66d07..e4034d280df8 100644 --- a/src/backend/out.c +++ b/src/backend/out.c @@ -1320,7 +1320,7 @@ STATIC void writefunc2(symbol *sfunc) sfunc->Sclass != SCsinline && !(sfunc->Sclass == SCinline && !(config.flags2 & CFG2comdat)) && sfunc->ty() & mTYexport) - objmod->export_symbol(sfunc,Poffset); // export function definition + objmod->export_symbol(sfunc,Para.offset); // export function definition if (config.fulltypes && config.fulltypes != CV8) cv_func(sfunc); // debug info for function diff --git a/src/glue.c b/src/glue.c index 5fa6fe87c894..5008b06b4b29 100644 --- a/src/glue.c +++ b/src/glue.c @@ -1039,7 +1039,7 @@ void FuncDeclaration::toObjFile(int multiobj) writefunc(s); if (isExport()) - objmod->export_symbol(s, Poffset); + objmod->export_symbol(s, Para.offset); for (size_t i = 0; i < irs.deferToObj->dim; i++) {