Skip to content

Commit

Permalink
Merge remote-tracking branch 'upstream/master'
Browse files Browse the repository at this point in the history
  • Loading branch information
Adam Wilson committed May 5, 2012
2 parents ede62e7 + 1a2f969 commit 156bb5c
Show file tree
Hide file tree
Showing 6 changed files with 118 additions and 57 deletions.
38 changes: 9 additions & 29 deletions src/backend/cgcod.c
Expand Up @@ -128,15 +128,7 @@ void codgen()
csmax = 64;
csextab = (struct CSE *) util_calloc(sizeof(struct CSE),csmax);
functy = tybasic(funcsym_p->ty());
#if TARGET_LINUX || TARGET_OSX || TARGET_FREEBSD || TARGET_OPENBSD || TARGET_SOLARIS
regm_t value = BYTEREGS_INIT;
ALLREGS = ALLREGS_INIT;
BYTEREGS = value;
if (I64)
{ ALLREGS = mAX|mBX|mCX|mDX|mSI|mDI| mR8|mR9|mR10|mR11|mR12|mR13|mR14|mR15;
BYTEREGS = ALLREGS;
}
#endif
cod3_initregs();
allregs = ALLREGS;
pass = PASSinit;

Expand Down Expand Up @@ -1853,21 +1845,15 @@ if (regcon.cse.mval & 1) elem_print(regcon.cse.value[i]);
csextab[i].flags |= CSEload;
if (*pretregs == mPSW) /* if result in CCs only */
{ // CMP cs[BP],0
c = genc(NULL,0x81 ^ byte,modregrm(2,7,BPRM),
FLcs,i, FLconst,(targ_uns) 0);
if (I32 && sz == 2)
c->Iflags |= CFopsize;
c = gen_testcse(NULL, sz, i);
}
else
{
retregs = *pretregs;
if (byte && !(retregs & BYTEREGS))
retregs = BYTEREGS;
c = allocreg(&retregs,&reg,tym);
// MOV reg,cs[BP]
c = genc1(c,0x8B,modregxrm(2,reg,BPRM),FLcs,(targ_uns) i);
if (I64)
code_orrex(c, REX_W);
c = gen_loadcse(c, reg, i);
L10:
regcon.cse.mval |= mask[reg]; // cs is in a reg
regcon.cse.value[reg] = e;
Expand Down Expand Up @@ -1995,10 +1981,8 @@ if (regcon.cse.mval & 1) elem_print(regcon.cse.value[i]);
*/

STATIC code * loadcse(elem *e,unsigned reg,regm_t regm)
{ unsigned i,op;
code *c;

for (i = cstop; i--;)
{
for (unsigned i = cstop; i--;)
{
//printf("csextab[%d] = %p, regm = x%x\n", i, csextab[i].e, csextab[i].regm);
if (csextab[i].e == e && csextab[i].regm & regm)
Expand All @@ -2007,7 +1991,8 @@ STATIC code * loadcse(elem *e,unsigned reg,regm_t regm)
csextab[i].flags |= CSEload; /* it was loaded */
regcon.cse.value[reg] = e;
regcon.cse.mval |= mask[reg];
return gen_loadcse(reg, i);
code *c = getregs(mask[reg]);
return gen_loadcse(c, reg, i);
}
}
#if DEBUG
Expand Down Expand Up @@ -2311,19 +2296,14 @@ code *scodelem(elem *e,regm_t *pretregs,regm_t keepmsk,bool constflag)
sz = -(adjesp & 7) & 7;
if (calledafunc && !I16 && sz && (STACKALIGN == 16 || config.flags4 & CFG4stackalign))
{
unsigned grex = I64 ? REX_W << 16 : 0;
regm_t mval_save = regcon.immed.mval;
regcon.immed.mval = 0; // prevent reghasvalue() optimizations
// because c hasn't been executed yet
cs1 = genc2(cs1,0x81,grex | modregrm(3,5,SP),sz); // SUB ESP,sz
if (I64)
code_orrex(cs1, REX_W);
cs1 = cod3_stackadj(cs1, sz);
regcon.immed.mval = mval_save;
cs1 = genadjesp(cs1, sz);

code *cx = genc2(CNIL,0x81,grex | modregrm(3,0,SP),sz); // ADD ESP,sz
if (I64)
code_orrex(cx, REX_W);
code *cx = cod3_stackadj(NULL, -sz);
cx = genadjesp(cx, -sz);
cs2 = cat(cx, cs2);
}
Expand Down
35 changes: 16 additions & 19 deletions src/backend/cgen.c
Expand Up @@ -64,6 +64,7 @@ void code_orflag(code *c,unsigned flag)
}
}

#if TX86
/*****************************
* Set rex bits on last code in list.
*/
Expand All @@ -76,6 +77,7 @@ void code_orrex(code *c,unsigned rex)
c->Irex |= rex;
}
}
#endif

/**************************************
* Set the opcode fields in cs.
Expand Down Expand Up @@ -164,34 +166,21 @@ code * cat6(code *c1,code *c2,code *c3,code *c4,code *c5,code *c6)
*/

code *gen(code *c,code *cs)
{ code *ce,*cstart;
unsigned reg;

{
#ifdef DEBUG /* this is a high usage routine */
assert(cs);
#endif
#if TX86
assert(I64 || cs->Irex == 0);
ce = code_calloc();
#endif
code* ce = code_calloc();
*ce = *cs;
//printf("ce = %p %02x\n", ce, ce->Iop);
ccheck(ce);
if (config.flags4 & CFG4optimized &&
(ce->Iop == 0x81 || ce->Iop == 0x80) &&
ce->IFL2 == FLconst &&
reghasvalue((ce->Iop == 0x80) ? BYTEREGS : ALLREGS,I64 ? ce->IEV2.Vsize_t : ce->IEV2.Vlong,&reg) &&
!(ce->Iflags & CFopsize && I16)
)
{ // See if we can replace immediate instruction with register instruction
static unsigned char regop[8] =
{ 0x00,0x08,0x10,0x18,0x20,0x28,0x30,0x38 };

//printf("replacing 0x%02x, val = x%lx\n",ce->Iop,ce->IEV2.Vlong);
ce->Iop = regop[(ce->Irm & modregrm(0,7,0)) >> 3] | (ce->Iop & 1);
code_newreg(ce, reg);
}
simplify_code(ce);
code_next(ce) = CNIL;
if (c)
{ cstart = c;
{ code* cstart = c;
while (code_next(c)) c = code_next(c); /* find end of list */
code_next(c) = ce; /* link into list */
return cstart;
Expand All @@ -205,7 +194,9 @@ code *gen1(code *c,unsigned op)
ce = code_calloc();
ce->Iop = op;
ccheck(ce);
#if TX86
assert(op != LEA);
#endif
if (c)
{ cstart = c;
while (code_next(c)) c = code_next(c); /* find end of list */
Expand All @@ -215,6 +206,7 @@ code *gen1(code *c,unsigned op)
return ce;
}

#if TX86
code *gen2(code *c,unsigned op,unsigned rm)
{ code *ce,*cstart;

Expand Down Expand Up @@ -250,6 +242,7 @@ code *gen2sib(code *c,unsigned op,unsigned rm,unsigned sib)
}
return cstart;
}
#endif

/********************************
* Generate an ASM sequence.
Expand All @@ -267,6 +260,7 @@ code *genasm(code *c,char *s,unsigned slen)
return cat(c,ce);
}

#if TX86
code *gencs(code *c,unsigned op,unsigned ea,unsigned FL2,symbol *s)
{ code cs;

Expand Down Expand Up @@ -329,6 +323,7 @@ code *genc(code *c,unsigned op,unsigned ea,unsigned FL1,targ_size_t EV1,unsigned
cs.IEV2.Vsize_t = EV2;
return gen(c,&cs);
}
#endif

/********************************
* Generate 'instruction' which is actually a line number.
Expand Down Expand Up @@ -387,6 +382,7 @@ code *genadjesp(code *c, int offset)
return c;
}

#if TX86
/********************************
* Generate 'instruction' which tells the scheduler that the fpu stack has
* changed.
Expand All @@ -406,6 +402,7 @@ code *genadjfpu(code *c, int offset)
else
return c;
}
#endif

/********************************
* Generate 'nop'
Expand Down
72 changes: 70 additions & 2 deletions src/backend/cod3.c
Expand Up @@ -291,6 +291,28 @@ int cod3_EA(code *c)
return ins & M;
}

/********************************
* setup ALLREGS and BYTEREGS
* called by: codgen
*/

void cod3_initregs()
{
// should probably be !TARGET_WINDOS insetad of a long list of some targets
#if TARGET_LINUX || TARGET_OSX || TARGET_FREEBSD || TARGET_OPENBSD || TARGET_SOLARIS
if (I64)
{
ALLREGS = mAX|mBX|mCX|mDX|mSI|mDI| mR8|mR9|mR10|mR11|mR12|mR13|mR14|mR15;
BYTEREGS = ALLREGS;
}
else
{
ALLREGS = ALLREGS_INIT;
BYTEREGS = BYTEREGS_INIT;
}
#endif
}

/********************************
* set initial global variable values
*/
Expand Down Expand Up @@ -384,6 +406,23 @@ void cod3_align()
cod3_align_bytes(nbytes);
#endif
}

code* cod3_stackadj(code* c, int nbytes)
{
unsigned grex = I64 ? REX_W << 16 : 0;
unsigned rm;
if (nbytes > 0)
rm = modregrm(3,5,SP); // SUB ESP,nbytes
else
{
nbytes = -nbytes;
rm = modregrm(3,0,SP); // ADD ESP,nbytes
}
c = genc2(c, 0x81, grex | rm, nbytes);
if (I64)
code_orrex(c, REX_W);
return c;
}

/*****************************
* Given a type, return a mask of
Expand Down Expand Up @@ -1765,9 +1804,18 @@ bool cse_simple(code *c, elem *e)
return false;
}

code* gen_loadcse(unsigned reg, targ_uns i)
code* gen_testcse(code *c, unsigned sz, targ_uns i)
{
bool byte = sz == 1;
c = genc(c,0x81 ^ byte,modregrm(2,7,BPRM),
FLcs,i, FLconst,(targ_uns) 0);
if (I32 && sz == 2)
c->Iflags |= CFopsize;
return c;
}

code* gen_loadcse(code *c, unsigned reg, targ_uns i)
{
code* c = getregs(mask[reg]);
unsigned op = 0x8B;
if (reg == ES)
{
Expand Down Expand Up @@ -4952,6 +5000,26 @@ STATIC void pinholeopt_unittest()
}
#endif

void simplify_code(code* c)
{
unsigned reg;
if (config.flags4 & CFG4optimized &&
(c->Iop == 0x81 || c->Iop == 0x80) &&
c->IFL2 == FLconst &&
reghasvalue((c->Iop == 0x80) ? BYTEREGS : ALLREGS,I64 ? c->IEV2.Vsize_t : c->IEV2.Vlong,&reg) &&
!(c->Iflags & CFopsize && I16)
)
{
// See if we can replace immediate instruction with register instruction
static unsigned char regop[8] =
{ 0x00,0x08,0x10,0x18,0x20,0x28,0x30,0x38 };

//printf("replacing 0x%02x, val = x%lx\n",c->Iop,c->IEV2.Vlong);
c->Iop = regop[(c->Irm & modregrm(0,7,0)) >> 3] | (c->Iop & 1);
code_newreg(c, reg);
}
}

/**************************
* Compute jump addresses for FLcode.
* Note: only works for forward referenced code.
Expand Down
6 changes: 5 additions & 1 deletion src/backend/code.h
Expand Up @@ -694,7 +694,8 @@ code *getregs (regm_t r );
code *getregs_imm (regm_t r );
code *cse_flush(int);
bool cse_simple(code *c, elem *e);
code* gen_loadcse(unsigned reg, targ_uns i);
code* gen_testcse(code *c, unsigned sz, targ_uns i);
code* gen_loadcse(code *c, unsigned reg, targ_uns i);
void cssave (elem *e , regm_t regm , unsigned opsflag );
bool evalinregister (elem *e );
regm_t getscratch();
Expand Down Expand Up @@ -783,11 +784,13 @@ extern int BPoff;

int cod3_EA(code *c);
regm_t cod3_useBP();
void cod3_initregs();
void cod3_setdefault();
void cod3_set32 (void );
void cod3_set64 (void );
void cod3_align_bytes (size_t nbytes);
void cod3_align (void );
code* cod3_stackadj(code* c, int nbytes);
regm_t regmask(tym_t tym, tym_t tyf);
void cgreg_dst_regs(unsigned *dst_integer_reg, unsigned *dst_float_reg);
void cgreg_set_priorities(tym_t ty, char **pseq, char **pseqmsw);
Expand Down Expand Up @@ -823,6 +826,7 @@ void assignaddr (block *bl );
void assignaddrc (code *c );
targ_size_t cod3_bpoffset(symbol *s);
void pinholeopt (code *c , block *bn );
void simplify_code(code *c);
void jmpaddr (code *c );
int code_match(code *c1,code *c2);
unsigned calcblksize (code *c);
Expand Down
12 changes: 6 additions & 6 deletions src/clone.c
Expand Up @@ -519,7 +519,7 @@ FuncDeclaration *StructDeclaration::buildPostBlit(Scope *sc)
if (v->storage_class & STCref)
continue;
Type *tv = v->type->toBasetype();
dinteger_t dim = (tv->ty == Tsarray ? 1 : 0);
dinteger_t dim = 1;
while (tv->ty == Tsarray)
{ TypeSArray *ta = (TypeSArray *)tv;
dim *= ((TypeSArray *)tv)->dim->toInteger();
Expand All @@ -528,7 +528,7 @@ FuncDeclaration *StructDeclaration::buildPostBlit(Scope *sc)
if (tv->ty == Tstruct)
{ TypeStruct *ts = (TypeStruct *)tv;
StructDeclaration *sd = ts->sym;
if (sd->postblit)
if (sd->postblit && dim)
{
stc |= sd->postblit->storage_class & STCdisable;

Expand All @@ -542,7 +542,7 @@ FuncDeclaration *StructDeclaration::buildPostBlit(Scope *sc)
Expression *ex = new ThisExp(0);
ex = new DotVarExp(0, ex, v, 0);

if (dim == 0)
if (v->type->toBasetype()->ty == Tstruct)
{ // this.v.postblit()
ex = new DotVarExp(0, ex, sd->postblit, 0);
ex = new CallExp(0, ex);
Expand Down Expand Up @@ -631,7 +631,7 @@ FuncDeclaration *AggregateDeclaration::buildDtor(Scope *sc)
if (v->storage_class & STCref)
continue;
Type *tv = v->type->toBasetype();
dinteger_t dim = (tv->ty == Tsarray ? 1 : 0);
dinteger_t dim = 1;
while (tv->ty == Tsarray)
{ TypeSArray *ta = (TypeSArray *)tv;
dim *= ((TypeSArray *)tv)->dim->toInteger();
Expand All @@ -640,14 +640,14 @@ FuncDeclaration *AggregateDeclaration::buildDtor(Scope *sc)
if (tv->ty == Tstruct)
{ TypeStruct *ts = (TypeStruct *)tv;
StructDeclaration *sd = ts->sym;
if (sd->dtor)
if (sd->dtor && dim)
{ Expression *ex;

// this.v
ex = new ThisExp(0);
ex = new DotVarExp(0, ex, v, 0);

if (dim == 0)
if (v->type->toBasetype()->ty == Tstruct)
{ // this.v.dtor()
ex = new DotVarExp(0, ex, sd->dtor, 0);
ex = new CallExp(0, ex);
Expand Down

0 comments on commit 156bb5c

Please sign in to comment.