From fadd2a3dd057dd788759228caec636a882ad6714 Mon Sep 17 00:00:00 2001 From: Walter Bright Date: Thu, 16 May 2013 23:25:10 -0700 Subject: [PATCH] harmonize with some D2 changes --- src/backend/cgcod.c | 310 +++++++++++++++++----------------------- src/backend/cgcs.c | 13 +- src/backend/cgelem.c | 31 +++- src/backend/cgen.c | 2 + src/backend/cgsched.c | 2 +- src/backend/cod2.c | 1 + src/backend/cod3.c | 44 +----- src/backend/code_stub.h | 2 + src/backend/code_x86.h | 1 + src/backend/el.c | 8 +- src/backend/gother.c | 9 ++ src/backend/ptrntab.c | 4 +- src/backend/rtlsym.h | 1 + src/iasm.c | 22 --- src/lexer.c | 2 +- src/libelf.c | 2 +- src/libmach.c | 2 +- src/libmscoff.c | 2 +- src/libomf.c | 2 +- src/mars.h | 8 -- src/msc.c | 6 +- src/mtype.c | 2 +- src/root/longdouble.c | 21 ++- src/root/root.c | 45 ++---- src/root/root.h | 1 + src/root/stringtable.c | 2 +- src/root/stringtable.h | 2 +- 27 files changed, 238 insertions(+), 309 deletions(-) diff --git a/src/backend/cgcod.c b/src/backend/cgcod.c index 85e5d1b6c699..9fad0b1f32af 100644 --- a/src/backend/cgcod.c +++ b/src/backend/cgcod.c @@ -129,12 +129,8 @@ static regm_t lastretregs,last2retregs,last3retregs,last4retregs,last5retregs; */ void codgen() -{ block *b,*bn; +{ bool flag; - targ_size_t swoffset,coffset; - tym_t functy; - unsigned nretblocks; // number of return blocks - code *cprolog; #if SCPP block *btry; #endif @@ -146,7 +142,7 @@ void codgen() cgreg_init(); csmax = 64; csextab = (struct CSE *) util_calloc(sizeof(struct CSE),csmax); - functy = tybasic(funcsym_p->ty()); + tym_t functy = tybasic(funcsym_p->ty()); cod3_initregs(); allregs = ALLREGS; pass = PASSinit; @@ -198,11 +194,11 @@ void codgen() memset(®con,0,sizeof(regcon)); regcon.cse.mval = regcon.cse.mops = 0; // no common subs yet msavereg = 0; - nretblocks = 0; + unsigned nretblocks = 0; mfuncreg = fregsaved; // so we can see which are used // (bit is cleared each time // we use one) - for (b = startblock; b; b = b->Bnext) + for (block* b = startblock; b; b = b->Bnext) { memset(&b->Bregcon,0,sizeof(b->Bregcon)); // Clear out values in registers if (b->Belem) resetEcomsub(b->Belem); // reset all the Ecomsubs @@ -243,7 +239,7 @@ void codgen() cgreg_reset(); for (dfoidx = 0; dfoidx < dfotop; dfoidx++) { regcon.used = msavereg | regcon.cse.mval; // registers already in use - b = dfo[dfoidx]; + block* b = dfo[dfoidx]; blcodgen(b); // gen code in depth-first order //printf("b->Bregcon.used = %s\n", regm_str(b->Bregcon.used)); cgreg_used(dfoidx,b->Bregcon.used); // gather register used information @@ -251,7 +247,7 @@ void codgen() } else { pass = PASSfinal; - for (b = startblock; b; b = b->Bnext) + for (block* b = startblock; b; b = b->Bnext) blcodgen(b); // generate the code for each block } regcon.immed.mval = 0; @@ -273,7 +269,7 @@ void codgen() pass = PASSreg; else pass = PASSfinal; - for (b = startblock; b; b = b->Bnext) + for (block* b = startblock; b; b = b->Bnext) { code_free(b->Bcode); b->Bcode = NULL; } @@ -299,17 +295,17 @@ void codgen() // Otherwise, jmp's to startblock will execute the prolog again assert(!startblock->Bpred); - cprolog = prolog(); // gen function start code + code* cprolog = prolog(); // gen function start code if (cprolog) pinholeopt(cprolog,NULL); // optimize funcoffset = Coffset; - coffset = Coffset; + targ_size_t coffset = Coffset; if (eecontext.EEelem) genEEcode(); - for (b = startblock; b; b = b->Bnext) + for (block* b = startblock; b; b = b->Bnext) { // We couldn't do this before because localsize was unknown switch (b->BC) @@ -348,7 +344,7 @@ void codgen() // Do jump optimization do { flag = FALSE; - for (b = startblock; b; b = b->Bnext) + for (block* b = startblock; b; b = b->Bnext) { if (b->Bflags & BFLjmpoptdone) /* if no more jmp opts for this blk */ continue; int i = branch(b,0); // see if jmp => jmp short @@ -357,7 +353,7 @@ void codgen() b->Bsize -= i; offset = b->Boffset + b->Bsize; - for (bn = b->Bnext; bn; bn = bn->Bnext) + for (block* bn = b->Bnext; bn; bn = bn->Bnext) { if (bn->Balign) { targ_size_t u = bn->Balign - 1; @@ -388,9 +384,9 @@ void codgen() // Compute starting offset for switch tables #if ELFOBJ || MACHOBJ - swoffset = (config.flags & CFGromable) ? coffset : CDoffset; + targ_size_t swoffset = (config.flags & CFGromable) ? coffset : CDoffset; #else - swoffset = (config.flags & CFGromable) ? coffset : Doffset; + targ_size_t swoffset = (config.flags & CFGromable) ? coffset : Doffset; #endif swoffset = align(0,swoffset); @@ -405,7 +401,7 @@ void codgen() } else { - for (b = startblock; b; b = b->Bnext) + for (block* b = startblock; b; b = b->Bnext) { if (b->BC == BCjmptab || b->BC == BCswitch) { b->Btableoffset = swoffset; /* offset of sw tab */ @@ -473,7 +469,7 @@ void codgen() // Write out switch tables flag = FALSE; // TRUE if last active block was a ret - for (b = startblock; b; b = b->Bnext) + for (block* b = startblock; b; b = b->Bnext) { switch (b->BC) { case BCjmptab: /* if jump table */ @@ -546,7 +542,7 @@ void codgen() ; } #endif - for (b = startblock; b; b = b->Bnext) + for (block* b = startblock; b; b = b->Bnext) { code_free(b->Bcode); b->Bcode = NULL; @@ -614,10 +610,7 @@ targ_size_t alignsection(targ_size_t base, unsigned alignment, int bias) code *prolog() { - SYMIDX si; bool enter; - unsigned xlocalsize; // amount to subtract from ESP to make room for locals - char guessneedframe; regm_t namedargs = 0; //printf("cod3.prolog() %s, needframe = %d, Auto.alignment = %d\n", funcsym_p->Sident, needframe, Auto.alignment); @@ -637,7 +630,7 @@ code *prolog() Lagain: spoff = 0; - guessneedframe = needframe; + char guessneedframe = needframe; // if (needframe && config.exe & (EX_LINUX | EX_FREEBSD | EX_SOLARIS) && !(usednteh & ~NTEHjmonitor)) // usednteh |= NTEHpassthru; @@ -735,7 +728,7 @@ code *prolog() //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; + unsigned xlocalsize = localsize; // amount to subtract from ESP to make room for locals if (tyf & mTYnaked) // if no prolog/epilog for function { @@ -1196,12 +1189,8 @@ void stackoffsets(int flags) STATIC void blcodgen(block *bl) { - code *c; - list_t bpl; - int refparamsave; regm_t mfuncregsave = mfuncreg; char *sflsave = NULL; - int anyspill; //dbg_printf("blcodgen(%p)\n",bl); @@ -1211,7 +1200,7 @@ STATIC void blcodgen(block *bl) assert(bl->Bregcon.immed.mval == 0); regcon.immed.mval = 0; // assume no previous contents in registers // regcon.cse.mval = 0; - for (bpl = bl->Bpred; bpl; bpl = list_next(bpl)) + for (list_t bpl = bl->Bpred; bpl; bpl = list_next(bpl)) { block *bp = list_block(bpl); if (bpl == bl->Bpred) @@ -1235,11 +1224,11 @@ STATIC void blcodgen(block *bl) regcon.cse.mops &= regcon.cse.mval; // Set regcon.mvar according to what variables are in registers for this block - c = NULL; + code* c = NULL; regcon.mvar = 0; regcon.mpvar = 0; regcon.indexregs = 1; - anyspill = 0; + int anyspill = 0; if (config.flags4 & CFG4optimized) { SYMIDX i; code *cload = NULL; @@ -1302,7 +1291,7 @@ STATIC void blcodgen(block *bl) //regsave.idx = 0; reflocal = 0; - refparamsave = refparam; + int refparamsave = refparam; refparam = 0; assert((regcon.cse.mops & regcon.cse.mval) == regcon.cse.mops); @@ -1394,7 +1383,7 @@ STATIC void cgcod_eh() stack = NULL; for (c = b->Bcode; c; c = code_next(c)) { - if ((c->Iop & 0xFF) == ESCAPE) + if ((c->Iop & ESCAPEmask) == ESCAPE) { c1 = NULL; switch (c->Iop & 0xFFFF00) @@ -1580,23 +1569,23 @@ unsigned findreg(regm_t regm */ void freenode(elem *e) -{ unsigned i; - - elem_debug(e); - //dbg_printf("freenode(%p) : comsub = %d, count = %d\n",e,e->Ecomsub,e->Ecount); - if (e->Ecomsub--) return; /* usage count */ - if (e->Ecount) /* if it was a CSE */ - { for (i = 0; i < arraysize(regcon.cse.value); i++) +{ + elem_debug(e); + //dbg_printf("freenode(%p) : comsub = %d, count = %d\n",e,e->Ecomsub,e->Ecount); + if (e->Ecomsub--) return; /* usage count */ + if (e->Ecount) /* if it was a CSE */ + { + for (unsigned i = 0; i < arraysize(regcon.cse.value); i++) { if (regcon.cse.value[i] == e) /* if a register is holding it */ { regcon.cse.mval &= ~mask[i]; regcon.cse.mops &= ~mask[i]; /* free masks */ } } - for (i = 0; i < cstop; i++) + for (unsigned i = 0; i < cstop; i++) { if (csextab[i].e == e) csextab[i].e = NULL; } - } + } } /********************************* @@ -1604,20 +1593,19 @@ void freenode(elem *e) */ STATIC void resetEcomsub(elem *e) -{ unsigned op; - +{ while (1) { elem_debug(e); e->Ecomsub = e->Ecount; - op = e->Eoper; + unsigned op = e->Eoper; if (!OTleaf(op)) - { if (OTbinary(op)) - resetEcomsub(e->E2); - e = e->E1; + { if (OTbinary(op)) + resetEcomsub(e->E2); + e = e->E1; } else - break; + break; } } @@ -1721,12 +1709,7 @@ code *allocreg(regm_t *pretregs,unsigned *preg,tym_t tym #endif { #if TX86 - regm_t r; - regm_t retregs; unsigned reg; - unsigned msreg,lsreg; - int count; - unsigned size; #if 0 if (pass == PASSfinal) @@ -1739,9 +1722,9 @@ code *allocreg(regm_t *pretregs,unsigned *preg,tym_t tym } #endif tym = tybasic(tym); - size = tysize[tym]; + unsigned size = tysize[tym]; *pretregs &= mES | allregs | XMMREGS; - retregs = *pretregs; + regm_t retregs = *pretregs; if ((retregs & regcon.mvar) == retregs) // if exactly in reg vars { if (size <= REGSIZE || (retregs & XMMREGS)) @@ -1756,15 +1739,15 @@ code *allocreg(regm_t *pretregs,unsigned *preg,tym_t tym assert(0); return getregs(retregs); } - count = 0; + int count = 0; L1: //printf("L1: allregs = %s, *pretregs = %s\n", regm_str(allregs), regm_str(*pretregs)); assert(++count < 20); /* fail instead of hanging if blocked */ assert(retregs); - msreg = lsreg = (unsigned)-1; /* no value assigned yet */ + unsigned msreg = -1, lsreg = -1; /* no value assigned yet */ L3: //printf("L2: allregs = %s, *pretregs = %s\n", regm_str(allregs), regm_str(*pretregs)); - r = retregs & ~(msavereg | regcon.cse.mval | regcon.params); + regm_t r = retregs & ~(msavereg | regcon.cse.mval | regcon.params); if (!r) { r = retregs & ~(msavereg | regcon.cse.mval); @@ -1912,10 +1895,9 @@ void useregs(regm_t regm) */ code *getregs(regm_t r) -{ regm_t ms; - +{ //printf("getregs(x%x) %s\n", r, regm_str(r)); - ms = r & regcon.cse.mops; // mask of common subs we must save + regm_t ms = r & regcon.cse.mops; // mask of common subs we must save useregs(r); regcon.cse.mval &= ~r; msavereg &= ~r; // regs that are destroyed @@ -1928,29 +1910,24 @@ code *getregs(regm_t r) */ STATIC code * cse_save(regm_t ms) -{ unsigned reg,i,op; +{ code *c = NULL; - regm_t regm; assert((ms & regcon.cse.mops) == ms); regcon.cse.mops &= ~ms; /* Skip CSEs that are already saved */ - for (regm = 1; regm < mask[NUMREGS]; regm <<= 1) + for (regm_t regm = 1; regm < mask[NUMREGS]; regm <<= 1) { if (regm & ms) - { elem *e; - - e = regcon.cse.value[findreg(regm)]; - for (i = 0; i < csmax; i++) + { + elem *e = regcon.cse.value[findreg(regm)]; + for (unsigned i = 0; i < csmax; i++) { if (csextab[i].e == e) { - tym_t tym; - unsigned sz; - - tym = e->Ety; - sz = tysize(tym); + tym_t tym = e->Ety; + unsigned sz = tysize(tym); if (sz <= REGSIZE || sz <= 2 * REGSIZE && (regm & mMSW && csextab[i].regm & mMSW || @@ -1968,7 +1945,7 @@ STATIC code * cse_save(regm_t ms) } } - for (i = cstop; ms; i++) + for (unsigned i = cstop; ms; i++) { if (i >= csmax) /* array overflow */ { unsigned cseinc; @@ -1992,7 +1969,7 @@ STATIC code * cse_save(regm_t ms) if (csextab[i].e == NULL || i >= cstop) { L1: - reg = findreg(ms); /* the register to save */ + unsigned reg = findreg(ms); /* the register to save */ csextab[i].e = regcon.cse.value[reg]; csextab[i].regm = mask[reg]; csextab[i].flags &= CSEload; @@ -2020,11 +1997,9 @@ STATIC code * cse_save(regm_t ms) */ code *getregs_imm(regm_t r) -{ code *c; - regm_t save; - - save = regcon.immed.mval; - c = getregs(r); +{ + regm_t save = regcon.immed.mval; + code* c = getregs(r); regcon.immed.mval = save; return c; } @@ -2036,10 +2011,9 @@ code *getregs_imm(regm_t r) */ code *cse_flush(int do87) -{ code *c; - +{ //dbg_printf("cse_flush()\n"); - c = cse_save(regcon.cse.mops); // save any CSEs to memory + code* c = cse_save(regcon.cse.mops); // save any CSEs to memory if (do87) c = cat(c,save87()); // save any 8087 temporaries return c; @@ -2106,61 +2080,56 @@ bool cssave(elem *e,regm_t regm,unsigned opsflag) */ bool evalinregister(elem *e) -{ regm_t emask; - unsigned i; - unsigned sz; - - if (config.exe == EX_WIN64 && e->Eoper == OPrelconst) - return TRUE; - - if (e->Ecount == 0) /* elem is not a CSE, therefore */ - /* we don't need to evaluate it */ - /* in a register */ - return FALSE; - if (EOP(e)) /* operators are always in register */ - return TRUE; - - // Need to rethink this code if float or double can be CSE'd - sz = tysize(e->Ety); - if (e->Ecount == e->Ecomsub) /* elem is a CSE that needs */ - /* to be generated */ +{ + if (config.exe == EX_WIN64 && e->Eoper == OPrelconst) + return TRUE; + + if (e->Ecount == 0) /* elem is not a CSE, therefore */ + /* we don't need to evaluate it */ + /* in a register */ + return FALSE; + if (EOP(e)) /* operators are always in register */ + return TRUE; + + // Need to rethink this code if float or double can be CSE'd + unsigned sz = tysize(e->Ety); + if (e->Ecount == e->Ecomsub) /* elem is a CSE that needs */ + /* to be generated */ + { + if ((I32 || I64) && + //pass == PASSfinal && // bug 8987 + sz <= REGSIZE) { - if ((I32 || I64) && - //pass == PASSfinal && // bug 8987 - sz <= REGSIZE) - { - // Do it only if at least 2 registers are available - regm_t m; - - m = allregs & ~regcon.mvar; - if (sz == 1) - m &= BYTEREGS; - if (m & (m - 1)) // if more than one register - { // Need to be at least 3 registers available, as - // addressing modes can use up 2. - while (!(m & 1)) - m >>= 1; + // Do it only if at least 2 registers are available + regm_t m = allregs & ~regcon.mvar; + if (sz == 1) + m &= BYTEREGS; + if (m & (m - 1)) // if more than one register + { // Need to be at least 3 registers available, as + // addressing modes can use up 2. + while (!(m & 1)) m >>= 1; - if (m & (m - 1)) - return TRUE; - } + m >>= 1; + if (m & (m - 1)) + return TRUE; } - return FALSE; } + return FALSE; + } - /* Elem is now a CSE that might have been generated. If so, and */ - /* it's in a register already, the computation should be done */ - /* using that register. */ - emask = 0; - for (i = 0; i < arraysize(regcon.cse.value); i++) - if (regcon.cse.value[i] == e) - emask |= mask[i]; - emask &= regcon.cse.mval; // mask of available CSEs - if (sz <= REGSIZE) - return emask != 0; /* the CSE is in a register */ - else if (sz <= 2 * REGSIZE) - return (emask & mMSW) && (emask & mLSW); - return TRUE; /* cop-out for now */ + /* Elem is now a CSE that might have been generated. If so, and */ + /* it's in a register already, the computation should be done */ + /* using that register. */ + regm_t emask = 0; + for (unsigned i = 0; i < arraysize(regcon.cse.value); i++) + if (regcon.cse.value[i] == e) + emask |= mask[i]; + emask &= regcon.cse.mval; // mask of available CSEs + if (sz <= REGSIZE) + return emask != 0; /* the CSE is in a register */ + else if (sz <= 2 * REGSIZE) + return (emask & mMSW) && (emask & mLSW); + return TRUE; /* cop-out for now */ } /******************************************************* @@ -2168,9 +2137,8 @@ bool evalinregister(elem *e) */ regm_t getscratch() -{ regm_t scratch; - - scratch = 0; +{ + regm_t scratch = 0; if (pass == PASSfinal) { scratch = allregs & ~(regcon.mvar | regcon.mpvar | regcon.cse.mval | @@ -2189,7 +2157,6 @@ STATIC code * comsub(elem *e,regm_t *pretregs) { tym_t tym; regm_t regm,emask,csemask; unsigned reg,i,byte,sz; - code *c; //printf("comsub(e = %p, *pretregs = %s)\n",e,regm_str(*pretregs)); elem_debug(e); @@ -2199,8 +2166,8 @@ STATIC code * comsub(elem *e,regm_t *pretregs) #endif assert(e->Ecomsub <= e->Ecount); - c = CNIL; - if (*pretregs == 0) goto done; /* no possible side effects anyway */ + code* c = CNIL; + if (*pretregs == 0) goto done; /* no possible side effects anyway */ if (tyfloating(e->Ety) && config.inline8087) return comsub87(e,pretregs); @@ -2209,7 +2176,7 @@ STATIC code * comsub(elem *e,regm_t *pretregs) /* have the right contents. */ emask = 0; - for (i = 0; i < arraysize(regcon.cse.value); i++) + for (unsigned i = 0; i < arraysize(regcon.cse.value); i++) { //dbg_printf("regcon.cse.value[%d] = %p\n",i,regcon.cse.value[i]); if (regcon.cse.value[i] == e) /* if contents are right */ @@ -2219,7 +2186,7 @@ STATIC code * comsub(elem *e,regm_t *pretregs) /* create mask of what's in csextab[] */ csemask = 0; - for (i = 0; i < cstop; i++) + for (unsigned i = 0; i < cstop; i++) { if (csextab[i].e) elem_debug(csextab[i].e); if (csextab[i].e == e) @@ -2258,7 +2225,7 @@ if (regcon.cse.mval & 1) elem_print(regcon.cse.value[i]); if (!EOP(e)) /* if not op or func */ goto reload; /* reload data */ - for (i = cstop; i--;) /* look through saved comsubs */ + for (unsigned i = cstop; i--;) /* look through saved comsubs */ if (csextab[i].e == e) /* found it */ { regm_t retregs; @@ -2460,7 +2427,6 @@ elem_print(e); code *codelem(elem *e,regm_t *pretregs,bool constflag) { code *c; Symbol *s; - unsigned op; #ifdef DEBUG if (debugw) @@ -2487,7 +2453,7 @@ code *codelem(elem *e,regm_t *pretregs,bool constflag) if (!constflag && *pretregs & (mES | ALLREGS | mBP | XMMREGS) & ~regcon.mvar) *pretregs &= ~regcon.mvar; /* can't use register vars */ - op = e->Eoper; + unsigned op = e->Eoper; if (e->Ecount && e->Ecount != e->Ecomsub) /* if common subexp */ { c = comsub(e,pretregs); goto L1; @@ -2595,11 +2561,7 @@ code *codelem(elem *e,regm_t *pretregs,bool constflag) code *scodelem(elem *e,regm_t *pretregs,regm_t keepmsk,bool constflag) { code *c,*cs1,*cs2,*cs3; - unsigned i,j; - regm_t oldmfuncreg,oldregcon,oldregimmed,overlap,tosave,touse; - int adjesp; - unsigned stackpushsave; - char calledafuncsave; + regm_t touse; #ifdef DEBUG if (debugw) @@ -2631,18 +2593,18 @@ code *scodelem(elem *e,regm_t *pretregs,regm_t keepmsk,bool constflag) return c; } } - overlap = msavereg & keepmsk; + regm_t overlap = msavereg & keepmsk; msavereg |= keepmsk; /* add to mask of regs to save */ - oldregcon = regcon.cse.mval; - oldregimmed = regcon.immed.mval; - oldmfuncreg = mfuncreg; /* remember old one */ + regm_t oldregcon = regcon.cse.mval; + regm_t oldregimmed = regcon.immed.mval; + regm_t oldmfuncreg = mfuncreg; /* remember old one */ mfuncreg = (XMMREGS | mBP | mES | ALLREGS) & ~regcon.mvar; - stackpushsave = stackpush; - calledafuncsave = calledafunc; + unsigned stackpushsave = stackpush; + char calledafuncsave = calledafunc; calledafunc = 0; c = codelem(e,pretregs,constflag); /* generate code for the elem */ - tosave = keepmsk & ~msavereg; /* registers to save */ + regm_t tosave = keepmsk & ~msavereg; /* registers to save */ if (tosave) { cgstate.stackclean++; c = genstackclean(c,stackpush - stackpushsave,*pretregs | msavereg); @@ -2687,16 +2649,18 @@ code *scodelem(elem *e,regm_t *pretregs,regm_t keepmsk,bool constflag) } cs1 = cs2 = cs3 = NULL; - adjesp = 0; + int adjesp = 0; - for (i = 0; tosave; i++) + for (unsigned i = 0; tosave; i++) { regm_t mi = mask[i]; assert(i < REGMAX); if (mi & tosave) /* i = register to save */ { if (touse) /* if any scratch registers */ - { for (j = 0; j < 8; j++) + { + unsigned j; + for (j = 0; j < 8; j++) { regm_t mj = mask[j]; if (touse & mj) @@ -2819,29 +2783,23 @@ const char *regm_str(regm_t rm) */ code *docommas(elem **pe) -{ elem *e; - code *cc; - unsigned stackpushsave; - int stackcleansave; - - stackpushsave = stackpush; - stackcleansave = cgstate.stackclean; +{ + unsigned stackpushsave = stackpush; + int stackcleansave = cgstate.stackclean; cgstate.stackclean = 0; - cc = CNIL; - e = *pe; + code* cc = CNIL; + elem* e = *pe; while (1) - { elem *eold; - regm_t retregs; - + { if (configv.addlinenumbers && e->Esrcpos.Slinnum) { cc = genlinnum(cc,e->Esrcpos); //e->Esrcpos.Slinnum = 0; // don't do it twice } if (e->Eoper != OPcomma) break; - retregs = 0; + regm_t retregs = 0; cc = cat(cc,codelem(e->E1,&retregs,TRUE)); - eold = e; + elem* eold = e; e = e->E2; freenode(eold); } diff --git a/src/backend/cgcs.c b/src/backend/cgcs.c index 8197da938c2d..1d8ae7178ccd 100644 --- a/src/backend/cgcs.c +++ b/src/backend/cgcs.c @@ -500,8 +500,7 @@ STATIC void addhcstab(elem *e,int hash) */ STATIC void touchlvalue(elem *e) -{ register int i; - +{ if (e->Eoper == OPind) /* if indirect store */ { /* NOTE: Some types of array assignments do not need @@ -513,12 +512,16 @@ STATIC void touchlvalue(elem *e) return; } - for (i = hcstop; --i >= 0;) - { if (hcstab[i].Helem && + for (int i = hcstop; --i >= 0;) + { if (hcstab[i].Helem && hcstab[i].Helem->EV.sp.Vsym == e->EV.sp.Vsym) hcstab[i].Helem = NULL; - } + } +#ifdef DEBUG + if (!(e->Eoper == OPvar || e->Eoper == OPrelconst)) + elem_print(e); +#endif assert(e->Eoper == OPvar || e->Eoper == OPrelconst); switch (e->EV.sp.Vsym->Sclass) { diff --git a/src/backend/cgelem.c b/src/backend/cgelem.c index 215be6eda037..226f70cb68bb 100644 --- a/src/backend/cgelem.c +++ b/src/backend/cgelem.c @@ -2245,10 +2245,18 @@ STATIC elem * eloror(elem *e, goal_t goal) { if (boolres(e1)) /* (x,1) || e2 => (x,1),1 */ { - L2: - e->Eoper = OPcomma; - el_free(e->E2); - e->E2 = el_int(t,1); + if (tybasic(e->E2->Ety) == TYvoid) + { assert(!goal); + el_free(e); + return NULL; + } + else + { + L2: + e->Eoper = OPcomma; + el_free(e->E2); + e->E2 = el_int(t,1); + } } else /* (x,0) || e2 => (x,0),(bool e2) */ { e->Eoper = OPcomma; @@ -2401,12 +2409,21 @@ STATIC elem * elandand(elem *e, goal_t goal) e->Eoper = OPcomma; if (boolres(e1)) /* (x,1) && e2 => (x,1),bool e2 */ { - e->E2 = el_una(OPbool,e->Ety,e->E2); + if (tybasic(e->E2->Ety) != TYvoid) + e->E2 = el_una(OPbool,e->Ety,e->E2); } else /* (x,0) && e2 => (x,0),0 */ { - el_free(e->E2); - e->E2 = el_int(e->Ety,0); + if (tybasic(e->E2->Ety) == TYvoid) + { assert(!goal); + el_free(e); + return NULL; + } + else + { + el_free(e->E2); + e->E2 = el_int(e->Ety,0); + } } } else diff --git a/src/backend/cgen.c b/src/backend/cgen.c index 166f06957161..f470a072c6e0 100644 --- a/src/backend/cgen.c +++ b/src/backend/cgen.c @@ -580,11 +580,13 @@ size_t addtofixlist(symbol *s,targ_size_t soffset,int seg,targ_size_t val,int fl if (I64 && !(flags & CFoffset64)) numbytes = 4; +#if TARGET_WINDOS /* This can happen when generating CV8 data */ if (flags & CFseg) numbytes += 2; #endif +#endif #ifdef DEBUG assert(numbytes <= sizeof(zeros)); #endif diff --git a/src/backend/cgsched.c b/src/backend/cgsched.c index 16a568688040..0e7208c849a5 100644 --- a/src/backend/cgsched.c +++ b/src/backend/cgsched.c @@ -2711,7 +2711,7 @@ code *schedule(code *c,regm_t scratch) while (c) { if ((c->Iop == NOP || - ((c->Iop & 0xFF) == ESCAPE && c->Iop != (ESCAPE | ESCadjfpu)) || + ((c->Iop & ESCAPEmask) == ESCAPE && c->Iop != (ESCAPE | ESCadjfpu)) || c->Iflags & CFclassinit) && !(c->Iflags & (CFtarg | CFtarg2))) { code *cn; diff --git a/src/backend/cod2.c b/src/backend/cod2.c index 43de6b087739..2f8ac05f5773 100644 --- a/src/backend/cod2.c +++ b/src/backend/cod2.c @@ -3261,6 +3261,7 @@ code *cdmemcmp(elem *e,regm_t *pretregs) #if 1 c3 = cat(c3,getregs(mAX)); c3 = gen2(c3,0x33,modregrm(3,AX,AX)); // XOR AX,AX + code_orflag(c3, CFpsw); // keep flags #else if (*pretregs != mPSW) // if not flags only c3 = regwithvalue(c3,mAX,0,NULL,0); // put 0 in AX diff --git a/src/backend/cod3.c b/src/backend/cod3.c index 5c2bee6661f1..b9bd0b2ea984 100644 --- a/src/backend/cod3.c +++ b/src/backend/cod3.c @@ -776,12 +776,6 @@ void outblkexitcode(block *bl, code*& c, int& anyspill, const char* sflsave, sym // Mark all registers as destroyed. This will prevent // register assignments to variables used in catch blocks. c = cat(c,getregs((I32 | I64) ? allregs : (ALLREGS | mES))); -#if 0 && TARGET_LINUX - if (config.flags3 & CFG3pic && !(allregs & mBX)) - { - c = cat(c, cod3_load_got()); - } -#endif goto case_goto; #endif #if SCPP @@ -789,12 +783,6 @@ void outblkexitcode(block *bl, code*& c, int& anyspill, const char* sflsave, sym // Mark all registers as destroyed. This will prevent // register assignments to variables used in catch blocks. c = cat(c,getregs(allregs | mES)); -#if 0 && TARGET_LINUX - if (config.flags3 & CFG3pic && !(allregs & mBX)) - { - c = cat(c, cod3_load_got()); - } -#endif goto case_goto; case BCtry: @@ -2527,7 +2515,10 @@ code *movregconst(code *c,unsigned reg,targ_size_t value,regm_t flags) if (flags & 64) c = genc2(c,0xC7,(REX_W << 16) | modregrmx(3,0,reg),value); // MOV reg,value64 else - c = genc2(c,0xC7,modregrmx(3,0,reg),value); // MOV reg,value + { c = genc2(c,0xC7,modregrmx(3,0,reg),value); // MOV reg,value + if (I64) + value &= 0xFFFFFFFF; + } } } done: @@ -3657,33 +3648,6 @@ targ_size_t cod3_spoff() return spoff + localsize; } -/********************************** - * Load value of _GLOBAL_OFFSET_TABLE_ into EBX - */ - -code *cod3_load_got() -{ -#if TARGET_LINUX || TARGET_OSX || TARGET_FREEBSD || TARGET_OPENBSD || TARGET_SOLARIS - code *c; - code *cgot; - - c = genc2(NULL,CALL,0,0); // CALL L1 - gen1(c, 0x58 + BX); // L1: POP EBX - - // ADD EBX,_GLOBAL_OFFSET_TABLE_+3 - symbol *gotsym = Obj::getGOTsym(); - cgot = gencs(CNIL,0x81,0xC3,FLextern,gotsym); - cgot->Iflags = CFoff; - cgot->IEVoffset2 = 3; - - makeitextern(gotsym); - return cat(c,cgot); -#else - assert(0); - return NULL; -#endif -} - code* gen_spill_reg(Symbol* s, bool toreg) { code *c; diff --git a/src/backend/code_stub.h b/src/backend/code_stub.h index dd6e1f4ae3e0..908a5897d7c4 100644 --- a/src/backend/code_stub.h +++ b/src/backend/code_stub.h @@ -4,6 +4,7 @@ #define ESCAPE 2 // 8 is to leave room for opcodes to be in the range 0 .. 255 // probably better off moving them to the high byte rather than second byte + #define ESCAPEmask 0xff #define ESClinnum (0 << 8) #define ESCadjesp (1 << 8) #define ESCadjfpu (2 << 8) @@ -84,5 +85,6 @@ struct code bool isJumpOP() { return false; } + void print() {} }; diff --git a/src/backend/code_x86.h b/src/backend/code_x86.h index 19d915aa7a42..bc7ab7a5d373 100644 --- a/src/backend/code_x86.h +++ b/src/backend/code_x86.h @@ -231,6 +231,7 @@ extern regm_t BYTEREGS; #define NOP 0x2E /* actually CS: (we don't use 0x90 because the */ /* silly Windows stuff wants to output 0x90's) */ +#define ESCAPEmask 0xFF // code.Iop & ESCAPEmask ==> actual Iop #define ESCAPE 0x3E // marker that special information is here // (Iop2 is the type of special information) // (Same as DS:, but we will never generate diff --git a/src/backend/el.c b/src/backend/el.c index c65dba471688..20a7d58b2b17 100644 --- a/src/backend/el.c +++ b/src/backend/el.c @@ -1105,7 +1105,13 @@ symbol *el_alloc_localgot() char name[15]; static int tmpnum; sprintf(name, "_LOCALGOT%d", tmpnum++); - localgot = symbol_name(name, SCauto, type_fake(TYnptr)); + type *t = type_fake(TYnptr); + /* Make it volatile because we need it for calling functions, but that isn't + * noticed by the data flow analysis. Hence, it may get deleted if we don't + * make it volatile. + */ + type_setcv(&t, mTYvolatile); + localgot = symbol_name(name, SCauto, t); symbol_add(localgot); localgot->Sfl = FLauto; localgot->Sflags = SFLfree | SFLunambig | GTregcand; diff --git a/src/backend/gother.c b/src/backend/gother.c index 15318b036923..3ad77f10d6ab 100644 --- a/src/backend/gother.c +++ b/src/backend/gother.c @@ -399,6 +399,15 @@ STATIC void chkrd(elem *n,list_t rdlist) if (sv->Stype->Ttag->Sstruct->Sflags & (STRbitfields | STR0size)) return; } +#if 0 + // If variable is zero length static array, don't print message. + // BUG: Suppress error even if variable is initialized with void. + if (sv->Stype->Tty == TYarray && sv->Stype->Tdim == 0) + { + printf("sv->Sident = %s\n", sv->Sident); + return; + } +#endif #if SCPP { Outbuffer buf; char *p2; diff --git a/src/backend/ptrntab.c b/src/backend/ptrntab.c index 7eb4de403c8e..350b0b309645 100644 --- a/src/backend/ptrntab.c +++ b/src/backend/ptrntab.c @@ -653,8 +653,8 @@ PTRNTAB2 aptb2MOVSXD[] = /* MOVSXD */ { { ASM_END } }; PTRNTAB2 aptb2MOVZX[] = /* MOVZX */ { - { 0x0fb6, _r|_16_bit, _r16, _rm8 }, - { 0x0fb6, _r|_32_bit, _r32, _rm8 }, + { 0x0fb6, _r|_16_bit, _r16, _rm8 }, + { 0x0fb6, _r|_32_bit, _r32, _rm8 }, { 0x0fb6, _r|_64_bit, _r64, _rm8 }, // TODO: REX_W override is implicit { 0x0fb7, _r|_16_bit, _r16, _rm16 }, { 0x0fb7, _r|_32_bit, _r32, _rm16 }, diff --git a/src/backend/rtlsym.h b/src/backend/rtlsym.h index 0b9d1ceb4f9e..0e0517c3b903 100644 --- a/src/backend/rtlsym.h +++ b/src/backend/rtlsym.h @@ -46,6 +46,7 @@ SYMBOL_MARS(MONITOR_HANDLER, FLfunc,FREGSAVED,"_d_monitor_handler", 0, 0) \ SYMBOL_MARS(MONITOR_PROLOG, FLfunc,FREGSAVED,"_d_monitor_prolog",0,t) \ SYMBOL_MARS(MONITOR_EPILOG, FLfunc,FREGSAVED,"_d_monitor_epilog",0,t) \ SYMBOL_MARS(DCOVER, FLfunc,FREGSAVED,"_d_cover_register", 0, t) \ +SYMBOL_MARS(DCOVER2, FLfunc,FREGSAVED,"_d_cover_register2", 0, t) \ SYMBOL_MARS(DASSERT, FLfunc,FREGSAVED,"_d_assert", SFLexit, t) \ SYMBOL_MARS(DASSERTM, FLfunc,FREGSAVED,"_d_assertm", SFLexit, t) \ SYMBOL_MARS(DASSERT_MSG, FLfunc,FREGSAVED,"_d_assert_msg", SFLexit, t) \ diff --git a/src/iasm.c b/src/iasm.c index 740708578b64..56a1741acddc 100644 --- a/src/iasm.c +++ b/src/iasm.c @@ -203,8 +203,6 @@ typedef struct char regstr[6]; unsigned char val; opflag_t ty; - - bool isSIL_DIL_BPL_SPL(); } REG; static REG regFp = { "ST", 0, _st }; @@ -443,16 +441,6 @@ static REG regtab64[] = "YMM15", 15, _ymm, }; -bool REG::isSIL_DIL_BPL_SPL() -{ - // Be careful as these have the same val's as AH CH DH BH - return ty == _r8 && - ((val == _SIL && strcmp(regstr, "SIL") == 0) || - (val == _DIL && strcmp(regstr, "DIL") == 0) || - (val == _BPL && strcmp(regstr, "BPL") == 0) || - (val == _SPL && strcmp(regstr, "SPL") == 0)); -} - typedef enum { ASM_JUMPTYPE_UNSPECIFIED, ASM_JUMPTYPE_SHORT, @@ -1944,11 +1932,6 @@ printf("usOpcode = %x\n", usOpcode); pc->Irex |= REX_B; assert(I64); } - else if (popnd1->base->isSIL_DIL_BPL_SPL()) - { - pc->Irex |= REX; - assert(I64); - } if (asmstate.ucItype == ITfloat) pc->Irm += reg; else @@ -1968,11 +1951,6 @@ printf("usOpcode = %x\n", usOpcode); pc->Irex |= REX_B; assert(I64); } - else if (popnd1->base->isSIL_DIL_BPL_SPL()) - { - pc->Irex |= REX; - assert(I64); - } if (asmstate.ucItype == ITfloat) pc->Irm += reg; else diff --git a/src/lexer.c b/src/lexer.c index 972d085d6d33..ee1a11fb4884 100644 --- a/src/lexer.c +++ b/src/lexer.c @@ -3064,7 +3064,7 @@ void Lexer::initKeywords() { unsigned nkeywords = sizeof(keywords) / sizeof(keywords[0]); - stringtable.init(6151); + stringtable._init(6151); if (global.params.Dversion == 1) nkeywords -= 2; diff --git a/src/libelf.c b/src/libelf.c index dde456990242..9a058011d1fe 100644 --- a/src/libelf.c +++ b/src/libelf.c @@ -77,7 +77,7 @@ Library *Library::factory() LibElf::LibElf() { libfile = NULL; - tab.init(); + tab._init(); } /*********************************** diff --git a/src/libmach.c b/src/libmach.c index 57b04e4b9cf2..d068110eb7bf 100644 --- a/src/libmach.c +++ b/src/libmach.c @@ -87,7 +87,7 @@ Library *Library::factory() LibMach::LibMach() { libfile = NULL; - tab.init(); + tab._init(); } /*********************************** diff --git a/src/libmscoff.c b/src/libmscoff.c index 662f20acfab8..0b1a664aed5e 100644 --- a/src/libmscoff.c +++ b/src/libmscoff.c @@ -103,7 +103,7 @@ Library *LibMSCoff_factory() LibMSCoff::LibMSCoff() { libfile = NULL; - tab.init(); + tab._init(); } /*********************************** diff --git a/src/libomf.c b/src/libomf.c index 8d81541c3e56..6f5d8f42aa50 100644 --- a/src/libomf.c +++ b/src/libomf.c @@ -87,7 +87,7 @@ Library *Library::factory() LibOMF::LibOMF() { libfile = NULL; - tab.init(); + tab._init(); } /*********************************** diff --git a/src/mars.h b/src/mars.h index 158ae282ba8f..e1a68823cb4c 100644 --- a/src/mars.h +++ b/src/mars.h @@ -342,14 +342,6 @@ typedef d_uns32 d_dchar; typedef long double real_t; #endif -// Modify OutBuffer::writewchar to write the correct size of wchar -#if _WIN32 -#define writewchar writeword -#else -// This needs a configuration test... -#define writewchar write4 -#endif - #ifdef IN_GCC #include "d-gcc-complex_t.h" #endif diff --git a/src/msc.c b/src/msc.c index f081a839f134..f85912711380 100644 --- a/src/msc.c +++ b/src/msc.c @@ -1,6 +1,6 @@ // Compiler implementation of the D programming language -// Copyright (c) 1999-2013 by Digital Mars +// Copyright (c) 1999-2012 by Digital Mars // All Rights Reserved // written by Walter Bright // http://www.digitalmars.com @@ -73,9 +73,7 @@ void backend_init() bool exe; #if TARGET_WINDOS exe = false; - if (params->dll) - ; - else if (params->run) + if (params->run) exe = true; // EXE file only optimizations else if (params->link && !global.params.deffile) exe = true; // EXE file only optimizations diff --git a/src/mtype.c b/src/mtype.c index 766076473a1d..6f90d8ff60d8 100644 --- a/src/mtype.c +++ b/src/mtype.c @@ -137,7 +137,7 @@ char Type::needThisPrefix() void Type::init() { - stringtable.init(1543); + stringtable._init(1543); Lexer::initKeywords(); mangleChar[Tarray] = 'A'; diff --git a/src/root/longdouble.c b/src/root/longdouble.c index 8852a8357469..6244c6cbb724 100644 --- a/src/root/longdouble.c +++ b/src/root/longdouble.c @@ -51,14 +51,15 @@ bool initFPU() int old_cw = _control87(_MCW_EM | _PC_64 | _RC_NEAR, _MCW_EM | _MCW_PC | _MCW_RC); #endif + _set_output_format(_TWO_DIGIT_EXPONENT); return true; } static bool doInitFPU = initFPU(); -#ifndef _WIN64 extern "C" { +#ifndef _WIN64 double ld_read(const longdouble* pthis) { double res; @@ -70,6 +71,8 @@ double ld_read(const longdouble* pthis) } return res; } +#endif // !_WIN64 + long long ld_readll(const longdouble* pthis) { #if 1 @@ -126,6 +129,7 @@ unsigned long long ld_readull(const longdouble* pthis) #endif } +#ifndef _WIN64 void ld_set(longdouble* pthis, double d) { __asm @@ -157,9 +161,9 @@ void ld_setull(longdouble* pthis, unsigned long long d) fstp tbyte ptr [eax] } } +#endif // !_WIN64 } // extern "C" -#endif // !_WIN64 longdouble ldexpl(longdouble ld, int exp) { @@ -519,6 +523,13 @@ size_t ld_sprint(char* str, int fmt, longdouble x) // fmt is 'a','A','f' or 'g' if(fmt != 'a' && fmt != 'A') { + if (ldouble((unsigned long long)x) == x) + { // ((1.5 -> 1 -> 1.0) == 1.5) is false + // ((1.0 -> 1 -> 1.0) == 1.0) is true + // see http://en.cppreference.com/w/cpp/io/c/fprintf + char format[] = {'%', '#', 'L', fmt, 0}; + return sprintf(str, format, ld_read(&x)); + } char format[] = { '%', fmt, 0 }; return sprintf(str, format, ld_read(&x)); } @@ -580,6 +591,12 @@ static bool unittest() ld_sprint(buffer, 'a', ld_pi); assert(strcmp(buffer, "0x1.921fb54442d1846ap+1") == 0); + ld_sprint(buffer, 'g', ldouble(2.0)); + assert(strcmp(buffer, "2.00000") == 0); + + ld_sprint(buffer, 'g', ldouble(1234567.89)); + assert(strcmp(buffer, "1.23457e+06") == 0); + longdouble ldb = ldouble(0.4); long long b = ldb; assert(b == 0); diff --git a/src/root/root.c b/src/root/root.c index 7417a6acc04b..a35e9aa7084d 100644 --- a/src/root/root.c +++ b/src/root/root.c @@ -981,6 +981,8 @@ void File::mark() int File::read() { + if (len) + return 0; // already read the file #if POSIX off_t size; ssize_t numread; @@ -1058,7 +1060,7 @@ int File::read() name = this->name->toChars(); h = CreateFileA(name,GENERIC_READ,FILE_SHARE_READ,NULL,OPEN_EXISTING, - FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN,0); + FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN,NULL); if (h == INVALID_HANDLE_VALUE) goto err1; @@ -1636,6 +1638,15 @@ void OutBuffer::prependbyte(unsigned b) offset++; } +void OutBuffer::writewchar(unsigned w) +{ +#if _WIN32 + writeword(w); +#else + write4(w); +#endif +} + void OutBuffer::writeword(unsigned w) { if (doindent && linehead @@ -1734,36 +1745,6 @@ void OutBuffer::align(size_t size) fill0(nbytes); } - -//////////////////////////////////////////////////////////////// -// The compiler shipped with Visual Studio 2005 (and possible -// other versions) does not support C99 printf format specfiers -// such as %z and %j -#if 0 && _MSC_VER -using std::string; -using std::wstring; - -template -inline void -search_and_replace(S& str, const S& what, const S& replacement) -{ - assert(!what.empty()); - size_t pos = str.find(what); - while (pos != S::npos) - { - str.replace(pos, what.size(), replacement); - pos = str.find(what, pos + replacement.size()); - } -} -#define WORKAROUND_C99_SPECIFIERS_BUG(S,tmp,f) \ - S tmp = f; \ - search_and_replace(fmt, S("%z"), S("%l")); \ - search_and_replace(fmt, S("%j"), S("%l")); \ - f = tmp.c_str(); -#else -#define WORKAROUND_C99_SPECIFIERS_BUG(S,tmp,f) -#endif - void OutBuffer::vprintf(const char *format, va_list args) { char buffer[128]; @@ -1771,8 +1752,6 @@ void OutBuffer::vprintf(const char *format, va_list args) unsigned psize; int count; - WORKAROUND_C99_SPECIFIERS_BUG(string, fmt, format); - p = buffer; psize = sizeof(buffer); for (;;) diff --git a/src/root/root.h b/src/root/root.h index 6cb36d69a6c9..5935d4b5ca18 100644 --- a/src/root/root.h +++ b/src/root/root.h @@ -258,6 +258,7 @@ struct OutBuffer : Object void writebyte(unsigned b) { writeByte(b); } void writeUTF8(unsigned b); void prependbyte(unsigned b); + void writewchar(unsigned w); void writeword(unsigned w); void writeUTF16(unsigned w); void write4(unsigned w); diff --git a/src/root/stringtable.c b/src/root/stringtable.c index 79f816359232..bc54dacdebeb 100644 --- a/src/root/stringtable.c +++ b/src/root/stringtable.c @@ -62,7 +62,7 @@ void StringValue::ctor(const char *p, size_t length) memcpy(this->lstring, p, length * sizeof(char)); } -void StringTable::init(size_t size) +void StringTable::_init(size_t size) { table = (void **)mem.calloc(size, sizeof(void *)); tabledim = size; diff --git a/src/root/stringtable.h b/src/root/stringtable.h index b2a8a26b1d28..2dd7a7be6aa6 100644 --- a/src/root/stringtable.h +++ b/src/root/stringtable.h @@ -53,7 +53,7 @@ struct StringTable size_t tabledim; public: - void init(size_t size = 37); + void _init(size_t size = 37); ~StringTable(); StringValue *lookup(const char *s, size_t len);