Skip to content

Commit

Permalink
fold in D2 eh changes
Browse files Browse the repository at this point in the history
  • Loading branch information
WalterBright committed May 26, 2011
1 parent af42044 commit 25f24d5
Show file tree
Hide file tree
Showing 9 changed files with 128 additions and 27 deletions.
19 changes: 16 additions & 3 deletions src/backend/cgcod.c
Expand Up @@ -404,6 +404,14 @@ void codgen()
debugw && printf("code jump optimization complete\n");
#endif

#if MARS
if (usednteh & NTEH_try)
{
// Do this before code is emitted because we patch some instructions
nteh_filltables();
}
#endif

// Compute starting offset for switch tables
#if ELFOBJ || MACHOBJ
swoffset = (config.flags & CFGromable) ? coffset : CDoffset;
Expand Down Expand Up @@ -520,8 +528,6 @@ void codgen()
retoffset = b->Boffset + b->Bsize - funcoffset;
break;
}
code_free(b->Bcode);
b->Bcode = NULL;
}
if (flag && configv.addlinenumbers && !(funcsym_p->ty() & mTYnaked))
/* put line number at end of function on the
Expand All @@ -533,6 +539,7 @@ void codgen()
#if MARS
if (usednteh & NTEH_try)
{
// Do this before code is emitted because we patch some instructions
nteh_gentables();
}
if (usednteh & EHtry)
Expand Down Expand Up @@ -561,6 +568,12 @@ void codgen()
;
}
#endif
for (b = startblock; b; b = b->Bnext)
{
code_free(b->Bcode);
b->Bcode = NULL;
}

}

// Mask of regs saved
Expand Down Expand Up @@ -1390,7 +1403,7 @@ STATIC void cgcod_eh()
if ((c->Iop & 0xFF) == ESCAPE)
{
c1 = NULL;
switch (c->Iop & 0xFF00)
switch (c->Iop & 0xFFFF00)
{
case ESCctor:
//printf("ESCctor\n");
Expand Down
2 changes: 1 addition & 1 deletion src/backend/cgelem.c
Expand Up @@ -4550,7 +4550,7 @@ STATIC elem * optelem(elem *e,HINT goal)
}
else /* unary operator */
{
assert(!e->E2 || op == OPinfo || op == OParraylength);
assert(!e->E2 || op == OPinfo || op == OParraylength || op == OPddtor);
if (!goal && !OTsideff(op))
{
tym_t tym = e->E1->Ety;
Expand Down
2 changes: 1 addition & 1 deletion src/backend/cgen.c
Expand Up @@ -328,7 +328,7 @@ code *genjmp(code *c,unsigned op,unsigned fltarg,block *targ)
cs.Iop = op & 0xFF;
cs.Iflags = 0;
cs.Irex = 0;
if (op != JMP) /* if not already long branch */
if (op != JMP && op != 0xE8) // if not already long branch
cs.Iflags = CFjmp16; /* assume long branch for op = 0x7x */
cs.IFL2 = fltarg; /* FLblock (or FLcode) */
cs.IEV2.Vblock = targ; /* target block (or code) */
Expand Down
60 changes: 60 additions & 0 deletions src/backend/cod2.c
Expand Up @@ -4651,7 +4651,28 @@ code *cdinfo(elem *e,regm_t *pretregs)

code *cddctor(elem *e,regm_t *pretregs)
{
#if MARS
/* Generate:
ESCAPE | ESCdctor
MOV sindex[BP],index
*/
usednteh |= EHcleanup;
if (config.exe == EX_NT)
usednteh |= NTEHcleanup;
assert(*pretregs == 0);
code cs;
cs.Iop = ESCAPE | ESCdctor;
cs.Iflags = 0;
cs.Irex = 0;
cs.IFL1 = FLctor;
cs.IEV1.Vtor = e;
code *c = gen(CNIL,&cs);
c = cat(c, nteh_gensindex(0)); // the actual index will be patched in later
// by except_fillInEHTable()
return c;
#else
return NULL;
#endif
}

/*******************************************
Expand All @@ -4660,7 +4681,46 @@ code *cddctor(elem *e,regm_t *pretregs)

code *cdddtor(elem *e,regm_t *pretregs)
{
#if MARS
/* Generate:
ESCAPE | ESCddtor
MOV sindex[BP],index
CALL dtor
JMP L1
Ldtor:
... e->E1 ...
RET
L1: NOP
*/
usednteh |= EHcleanup;
if (config.exe == EX_NT)
usednteh |= NTEHcleanup;

code cs;
cs.Iop = ESCAPE | ESCddtor;
cs.Iflags = 0;
cs.Irex = 0;
cs.IFL1 = FLdtor;
cs.IEV1.Vtor = e;
code *cd = gen(CNIL,&cs);

cd = cat(cd, nteh_gensindex(0)); // the actual index will be patched in later
// by except_fillInEHTable()

assert(*pretregs == 0);
code *c = codelem(e->E1,pretregs,FALSE);
gen1(c,0xC3); // RET

genjmp(cd,0xE8,FLcode,(block *)c); // CALL Ldtor

code *cnop = gennop(CNIL);

genjmp(cd,JMP,FLcode,(block *)cnop);

return cat4(cd, c, cnop, NULL);
#else
return NULL;
#endif
}


Expand Down
36 changes: 19 additions & 17 deletions src/backend/cod3.c
Expand Up @@ -551,7 +551,7 @@ void doswitch(block *b)
code *cgot;

ce = cat(ce, getregs(mDX));
cx = genc2(NULL,0xE8,0,0); // CALL L1
cx = genc2(NULL,CALL,0,0); // CALL L1
gen1(cx, 0x58 + DI); // L1: POP EDI

// ADD EDI,_GLOBAL_OFFSET_TABLE_+3
Expand Down Expand Up @@ -1021,7 +1021,7 @@ void cod3_ptrchk(code **pc,code *pcs,regm_t keepmsk)
used &= ~(keepmsk | idxregs); // regs destroyed by this exercise
c = cat(c,getregs(used));
// CALL __ptrchk
gencs(c,(LARGECODE) ? 0x9A : 0xE8,0,FLfunc,rtlsym[RTLSYM_PTRCHK]);
gencs(c,(LARGECODE) ? 0x9A : CALL,0,FLfunc,rtlsym[RTLSYM_PTRCHK]);
}

*pc = cat(c,cs2);
Expand Down Expand Up @@ -1124,7 +1124,7 @@ code *cdgot(elem *e, regm_t *pretregs)
retregs = allregs;
c = allocreg(&retregs, &reg, TYnptr);

c = genc(c,0xE8,0,0,0,FLgot,0); // CALL L1
c = genc(c,CALL,0,0,0,FLgot,0); // CALL L1
gen1(c, 0x58 + reg); // L1: POP reg

return cat(c,fixresult(e,retregs,pretregs));
Expand All @@ -1139,7 +1139,7 @@ code *cdgot(elem *e, regm_t *pretregs)
retregs = allregs;
c = allocreg(&retregs, &reg, TYnptr);

c = genc2(c,0xE8,0,0); // CALL L1
c = genc2(c,CALL,0,0); // CALL L1
gen1(c, 0x58 + reg); // L1: POP reg

// ADD reg,_GLOBAL_OFFSET_TABLE_+3
Expand Down Expand Up @@ -1512,7 +1512,7 @@ code *prolog()
c = movregconst(c,AX,xlocalsize,FALSE); // MOV AX,localsize
makeitextern(rtlsym[RTLSYM_CHKSTK]);
// CALL _chkstk
gencs(c,(LARGECODE) ? 0x9A : 0xE8,0,FLfunc,rtlsym[RTLSYM_CHKSTK]);
gencs(c,(LARGECODE) ? 0x9A : CALL,0,FLfunc,rtlsym[RTLSYM_CHKSTK]);
useregs((ALLREGS | mBP | mES) & ~rtlsym[RTLSYM_CHKSTK]->Sregsaved);
}
else
Expand Down Expand Up @@ -1640,7 +1640,7 @@ code *prolog()

symbol *s = rtlsym[farfunc ? RTLSYM_TRACE_PRO_F : RTLSYM_TRACE_PRO_N];
makeitextern(s);
c = gencs(c,I16 ? 0x9A : 0xE8,0,FLfunc,s); // CALL _trace
c = gencs(c,I16 ? 0x9A : CALL,0,FLfunc,s); // CALL _trace
if (!I16)
code_orflag(c,CFoff | CFselfrel);
/* Embedding the function name inline after the call works, but it
Expand Down Expand Up @@ -2089,7 +2089,7 @@ void epilog(block *b)
{
symbol *s = rtlsym[farfunc ? RTLSYM_TRACE_EPI_F : RTLSYM_TRACE_EPI_N];
makeitextern(s);
c = gencs(c,I16 ? 0x9A : 0xE8,0,FLfunc,s); // CALLF _trace
c = gencs(c,I16 ? 0x9A : CALL,0,FLfunc,s); // CALLF _trace
if (!I16)
code_orflag(c,CFoff | CFselfrel);
useregs((ALLREGS | mBP | mES) & ~s->Sregsaved);
Expand Down Expand Up @@ -2247,7 +2247,7 @@ void epilog(block *b)
}
#if 0 // These optimizations don't work if the called function
// cleans off the stack.
else if (c->Iop == 0xC3 && cr->Iop == 0xE8) // CALL near
else if (c->Iop == 0xC3 && cr->Iop == CALL) // CALL near
{ cr->Iop = 0xE9; // JMP near
c->Iop = NOP;
}
Expand Down Expand Up @@ -2281,7 +2281,7 @@ code *cod3_load_got()
code *c;
code *cgot;

c = genc2(NULL,0xE8,0,0); // CALL L1
c = genc2(NULL,CALL,0,0); // CALL L1
gen1(c, 0x58 + BX); // L1: POP EBX

// ADD EBX,_GLOBAL_OFFSET_TABLE_+3
Expand Down Expand Up @@ -2639,7 +2639,7 @@ int branch(block *bl,int flag)
config.target_cpu >= TARGET_80386 &&
disp == (I16 ? 3 : 5) &&
cn &&
cn->Iop == 0xE8 &&
cn->Iop == CALL &&
cn->IFL2 == FLfunc &&
cn->IEVsym2->Sflags & SFLexit &&
!(cn->Iflags & (CFtarg | CFtarg2))
Expand Down Expand Up @@ -3688,7 +3688,7 @@ void jmpaddr(code *c)
if (op <= 0xEB &&
inssize[op] & T && // if second operand
c->IFL2 == FLcode &&
((op & ~0x0F) == 0x70 || op == JMP || op == JMPS || op == JCXZ))
((op & ~0x0F) == 0x70 || op == JMP || op == JMPS || op == JCXZ || op == CALL))
{ ci = code_next(c);
ctarg = c->IEV2.Vcode; /* target code */
ad = 0; /* IP displacement */
Expand All @@ -3699,7 +3699,7 @@ void jmpaddr(code *c)
}
if (!ci)
goto Lbackjmp; // couldn't find it
if (!I16 || op == JMP || op == JMPS || op == JCXZ)
if (!I16 || op == JMP || op == JMPS || op == JCXZ || op == CALL)
c->IEVpointer2 = ad;
else /* else conditional */
{ if (!(c->Iflags & CFjmp16)) /* if branch */
Expand Down Expand Up @@ -4080,7 +4080,7 @@ unsigned codout(code *c)
ins = inssize[op & 0xFF];
switch (op & 0xFF)
{ case ESCAPE:
switch (op & 0xFF00)
switch (op & 0xFFFF00)
{ case ESClinnum:
/* put out line number stuff */
objlinnum(c->IEV2.Vsrcpos,OFFSET());
Expand Down Expand Up @@ -4351,8 +4351,8 @@ unsigned codout(code *c)
else
goto case_default;

case 0xE8: // CALL rel
case 0xE9: // JMP rel
case CALL: // CALL rel
case JMP: // JMP rel
flags |= CFselfrel;
goto case_default;

Expand Down Expand Up @@ -4414,8 +4414,8 @@ unsigned codout(code *c)
else
goto case_default16;

case 0xE8:
case 0xE9:
case CALL:
case JMP:
flags |= CFselfrel;
default:
case_default16:
Expand Down Expand Up @@ -5039,10 +5039,12 @@ void code_hydrate(code **pc)
case FLblockoff:
(void) ph_hydrate(&c->IEV1.Vblock);
break;
#if SCPP
case FLctor:
case FLdtor:
el_hydrate(&c->IEV1.Vtor);
break;
#endif
case FLasm:
(void) ph_hydrate(&c->IEV1.as.bytes);
break;
Expand Down
6 changes: 4 additions & 2 deletions src/backend/code.c
@@ -1,5 +1,5 @@
// Copyright (C) 1987-1998 by Symantec
// Copyright (C) 2000-2009 by Digital Mars
// Copyright (C) 2000-2011 by Digital Mars
// All Rights Reserved
// http://www.digitalmars.com
// Written by Walter Bright
Expand Down Expand Up @@ -29,7 +29,7 @@ static code *code_list;

__declspec(naked) code *code_calloc()
{
if (sizeof(code) != 0x24)
if (sizeof(code) != 0x28)
util_assert("code",__LINE__);
__asm
{
Expand Down Expand Up @@ -58,6 +58,8 @@ L20: push sizeof(code)

mov 28[EAX],ECX
mov 32[EAX],ECX

mov 36[EAX],ECX
ret
}
}
Expand Down
4 changes: 4 additions & 0 deletions src/backend/code.h
Expand Up @@ -196,6 +196,7 @@ extern regm_t BYTEREGS;
#define SEGFS 0x64
#define SEGGS 0x65

#define CALL 0xE8
#define JMP 0xE9 /* Intra-Segment Direct */
#define JMPS 0xEB /* JMP SHORT */
#define JCXZ 0xE3
Expand Down Expand Up @@ -241,6 +242,8 @@ extern regm_t BYTEREGS;
#define ESCmark2 (8 << 8) // mark eh stack
#define ESCrelease2 (9 << 8) // release eh stack
#define ESCframeptr (10 << 8) // replace with load of frame pointer
#define ESCdctor (11 << 8) // D object is constructed
#define ESCddtor (12 << 8) // D object is destructed

#define ASM 0x36 // string of asm bytes, actually an SS: opcode

Expand Down Expand Up @@ -834,6 +837,7 @@ regm_t iasm_regs( block *bp );
code *nteh_prolog(void);
code *nteh_epilog(void);
void nteh_usevars(void);
void nteh_filltables(void);
void nteh_gentables(void);
code *nteh_setsp(int op);
code *nteh_filter(block *b);
Expand Down
8 changes: 7 additions & 1 deletion src/backend/el.c
Expand Up @@ -2398,6 +2398,9 @@ elem *el_dctor(elem *e,void *decl)
if (e)
e = el_bin(OPinfo,e->Ety,ector,e);
else
/* Remember that a "constructor" may execute no code, hence
* the need for OPinfo if there is code to execute.
*/
e = ector;
return e;
}
Expand All @@ -2413,6 +2416,10 @@ elem *el_dctor(elem *e,void *decl)
#if MARS
elem *el_ddtor(elem *e,void *decl)
{
/* A destructor always executes code, or we wouldn't need
* eh for it.
* An OPddtor must match 1:1 with an OPdctor
*/
elem *edtor = el_calloc();
edtor->Eoper = OPddtor;
edtor->Ety = TYvoid;
Expand Down Expand Up @@ -2461,7 +2468,6 @@ elem *el_ctor(elem *ector,elem *e,symbol *sdtor)
else
{
ector = el_unat(OPctor,ector->ET,ector);
symbol_debug(sdtor);
ector->EV.eop.Edtor = sdtor;
symbol_debug(sdtor);
if (e)
Expand Down

0 comments on commit 25f24d5

Please sign in to comment.