Skip to content

Commit

Permalink
Fix Issue 15103 - Improve declaration / initialization syntax error m…
Browse files Browse the repository at this point in the history
…essage
  • Loading branch information
adelavais committed Jul 30, 2020
2 parents 70c981c + 68bd67e commit 59c008e
Show file tree
Hide file tree
Showing 5 changed files with 166 additions and 114 deletions.
166 changes: 102 additions & 64 deletions src/dmd/backend/cod2.d
Expand Up @@ -1351,64 +1351,11 @@ void cddiv(ref CodeBuilder cdb,elem *e,regm_t *pretregs)
return;
}

uint lib;
regm_t keepregs = 0;
regm_t resreg;
ubyte op;
const uns = tyuns(tyml) || tyuns(e2.Ety); // 1 if uint operation, 0 if not

switch (oper)
{
case OPdiv:
resreg = mAX;
op = 7 - uns;
lib = uns ? CLIB.uldiv : CLIB.ldiv;
if (I32)
keepregs |= mSI | mDI;
break;

case OPmod:
resreg = mDX;
op = 7 - uns;
lib = uns ? CLIB.ulmod : CLIB.lmod;
if (I32)
keepregs |= mSI | mDI;
break;

case OPremquo:
resreg = mDX | mAX;
op = 7 - uns;
lib = uns ? CLIB.uldiv : CLIB.ldiv;
if (I32)
keepregs |= mSI | mDI;
break;

default:
assert(0);
}

regm_t retregs;
regm_t rretregs;
const isbyte = tybyte(e.Ety) != 0;
const sz = _tysize[tyml];
if (sz <= REGSIZE) // dedicated regs for mul & div
{ retregs = mAX;
// pick some other regs
rretregs = isbyte ? BYTEREGS & ~mAX
: ALLREGS & ~(mAX|mDX);
}
else
{
assert(sz <= 2 * REGSIZE);
retregs = mDX | mAX;
rretregs = mCX | mBX; // second arg
}

reg_t rreg;

const ubyte rex = (I64 && sz == 8) ? REX_W : 0;
const uint grex = rex << 16;
const OPER opunslng = I16 ? OPu16_32 : OPu32_64;

code cs = void;
cs.Iflags = 0;
Expand Down Expand Up @@ -1620,6 +1567,7 @@ void cddiv(ref CodeBuilder cdb,elem *e,regm_t *pretregs)
r3 = DX;
}

regm_t resreg;
switch (oper)
{ case OPdiv:
// r3 = quotient
Expand Down Expand Up @@ -1687,6 +1635,7 @@ void cddiv(ref CodeBuilder cdb,elem *e,regm_t *pretregs)
I32 // not set up for I64 cent yet
)
{
regm_t retregs = mDX | mAX;
if (pow2 == 63 && !(retregs & BYTEREGS & mLSW))
retregs = (retregs & mMSW) | (BYTEREGS & mLSW); // because of SETZ

Expand Down Expand Up @@ -1781,6 +1730,7 @@ void cddiv(ref CodeBuilder cdb,elem *e,regm_t *pretregs)
I32 // not set up for I64 cent yet
)
{
regm_t retregs = mDX | mAX;
codelem(cdb,e.EV.E1,&retregs,false); // eval left leaf
const rhi = findregmsw(retregs);
const rlo = findreglsw(retregs);
Expand Down Expand Up @@ -1862,7 +1812,7 @@ void cddiv(ref CodeBuilder cdb,elem *e,regm_t *pretregs)
ADD reg,r
SAR reg,1
*/
retregs = allregs;
regm_t retregs = allregs;
codelem(cdb,e.EV.E1,&retregs,false); // eval left leaf
const reg = findreg(retregs);
freenode(e2);
Expand All @@ -1875,10 +1825,31 @@ void cddiv(ref CodeBuilder cdb,elem *e,regm_t *pretregs)
cdb.genc2(0xC1,grex | modregxrmx(3,5,r),(sz * 8 - 1)); // SHR r,31
cdb.gen2(0x03,grex | modregxrmx(3,reg,r)); // ADD reg,r
cdb.gen2(0xD1,grex | modregrmx(3,7,reg)); // SAR reg,1
resreg = retregs;
regm_t resreg = retregs;
fixresult(cdb,e,resreg,pretregs);
return;
}

regm_t resreg;
switch (oper)
{
case OPdiv:
resreg = mAX;
break;

case OPmod:
resreg = mDX;
break;

case OPremquo:
resreg = mDX | mAX;
break;

default:
assert(0);
}

regm_t retregs = mAX;
codelem(cdb,e.EV.E1,&retregs,false); // eval left leaf
freenode(e2);
getregs(cdb,mAX | mDX); // modify these regs
Expand Down Expand Up @@ -1932,29 +1903,77 @@ void cddiv(ref CodeBuilder cdb,elem *e,regm_t *pretregs)

default: // OPconst and operators
//printf("test2 %p, retregs = %s rretregs = %s resreg = %s\n", e, regm_str(retregs), regm_str(rretregs), regm_str(resreg));
regm_t retregs = sz <= REGSIZE ? mAX : mDX | mAX;
codelem(cdb,e1,&retregs,false); // eval left leaf
regm_t rretregs;
if (sz <= REGSIZE) // dedicated regs for div
{
// pick some other regs
rretregs = isbyte ? BYTEREGS & ~mAX
: ALLREGS & ~(mAX|mDX);
}
else
{
assert(sz <= 2 * REGSIZE);
rretregs = mCX | mBX; // second arg
}
scodelem(cdb,e2,&rretregs,retregs,true); // get rvalue
if (sz <= REGSIZE)
{
getregs(cdb,mAX | mDX); // trash these regs
if (op == 7) // signed divide
{
cdb.gen1(0x99); // CWD
code_orrex(cdb.last(),rex);
}
else if (op == 6) // uint divide
if (uns) // unsigned divide
{
movregconst(cdb,DX,0,(sz == 8) ? 64 : 0); // MOV DX,0
getregs(cdb,mDX);
}
rreg = findreg(rretregs);
cdb.gen2(0xF7 ^ isbyte,grex | modregrmx(3,op,rreg)); // OP AX,rreg
else
{
cdb.gen1(0x99); // CWD
code_orrex(cdb.last(),rex);
}
reg_t rreg = findreg(rretregs);
cdb.gen2(0xF7 ^ isbyte,grex | modregrmx(3,7 - uns,rreg)); // OP AX,rreg
if (I64 && isbyte && rreg >= 4)
code_orrex(cdb.last(), REX);
regm_t resreg;
switch (oper)
{
case OPdiv:
resreg = mAX;
break;

case OPmod:
resreg = mDX;
break;

case OPremquo:
resreg = mDX | mAX;
break;

default:
assert(0);
}
fixresult(cdb,e,resreg,pretregs);
}
else if (sz == 2 * REGSIZE)
{
uint lib;
switch (oper)
{
case OPdiv:
case OPremquo:
lib = uns ? CLIB.uldiv : CLIB.ldiv;
break;

case OPmod:
lib = uns ? CLIB.ulmod : CLIB.lmod;
break;

default:
assert(0);
}

regm_t keepregs = I32 ? mSI | mDI : 0;
callclib(cdb,e,lib,pretregs,keepregs);
}
else
Expand All @@ -1966,11 +1985,30 @@ void cddiv(ref CodeBuilder cdb,elem *e,regm_t *pretregs)
goto default; // have to handle it with codelem()

// loadea() handles CWD or CLR DX for divides
regm_t retregs = mAX;
codelem(cdb,e.EV.E1,&retregs,false); // eval left leaf
loadea(cdb,e2,&cs,0xF7 ^ isbyte,op,0,
loadea(cdb,e2,&cs,0xF7 ^ isbyte,7 - uns,0,
mAX | mDX,
mAX | mDX);
freenode(e2);
regm_t resreg;
switch (oper)
{
case OPdiv:
resreg = mAX;
break;

case OPmod:
resreg = mDX;
break;

case OPremquo:
resreg = mDX | mAX;
break;

default:
assert(0);
}
fixresult(cdb,e,resreg,pretregs);
return;
}
Expand Down
63 changes: 28 additions & 35 deletions src/dmd/backend/cod4.d
Expand Up @@ -1707,23 +1707,11 @@ void cdmulass(ref CodeBuilder cdb,elem *e,regm_t *pretregs)

void cddivass(ref CodeBuilder cdb,elem *e,regm_t *pretregs)
{
code cs;
regm_t retregs;
reg_t resreg;
reg_t reg;
uint opr,lib,isbyte;

//printf("cddivass(e=%p, *pretregs = %s)\n",e,regm_str(*pretregs));
elem *e1 = e.EV.E1;
elem *e2 = e.EV.E2;
OPER op = e.Eoper; // OPxxxx

tym_t tyml = tybasic(e1.Ety); // type of lvalue
char uns = tyuns(tyml) || tyuns(e2.Ety);
uint sz = _tysize[tyml];

uint rex = (I64 && sz == 8) ? REX_W : 0;
uint grex = rex << 16; // 64 bit operands
OPER op = e.Eoper; // OPxxxx

// See if evaluate in XMM registers
if (config.fpxmmregs && tyxmmreg(tyml) && op != OPmodass && !(*pretregs & mST0))
Expand All @@ -1745,17 +1733,19 @@ void cddivass(ref CodeBuilder cdb,elem *e,regm_t *pretregs)
return;
}

code cs = void;

//printf("cddivass(e=%p, *pretregs = %s)\n",e,regm_str(*pretregs));
char uns = tyuns(tyml) || tyuns(e2.Ety);
uint sz = _tysize[tyml];

uint rex = (I64 && sz == 8) ? REX_W : 0;
uint grex = rex << 16; // 64 bit operands

if (sz <= REGSIZE) // if word or byte
{
isbyte = (sz == 1); // 1 for byte operation
resreg = AX; // result register for * or /
if (uns) // if uint operation
opr = 6; // DIV
else // else signed
opr = 7; // IDIV
if (op == OPmodass)
resreg = DX; // remainder is in DX

uint isbyte = (sz == 1); // 1 for byte operation
reg_t resreg;
targ_size_t e2factor;
int pow2;

Expand Down Expand Up @@ -1820,10 +1810,10 @@ void cddivass(ref CodeBuilder cdb,elem *e,regm_t *pretregs)
}
else
{
retregs = ALLREGS & ~(mAX|mDX); // DX gets sign extension
codelem(cdb,e2,&retregs,false); // load rvalue in retregs
reg = findreg(retregs);
getlvalue(cdb,&cs,e1,mAX | mDX | retregs); // get EA
regm_t retregs = ALLREGS & ~(mAX|mDX); // DX gets sign extension
codelem(cdb,e2,&retregs,false); // load rvalue in retregs
reg_t reg = findreg(retregs);
getlvalue(cdb,&cs,e1,mAX | mDX | retregs); // get EA
getregs(cdb,mAX | mDX); // destroy these regs
cs.Irm |= modregrm(0,AX,0);
cs.Iop = 0x8B;
Expand All @@ -1836,8 +1826,10 @@ void cddivass(ref CodeBuilder cdb,elem *e,regm_t *pretregs)
code_orrex(cdb.last(),rex);
}
getregs(cdb,mDX | mAX); // DX and AX will be destroyed
const uint opr = uns ? 6 : 7; // DIV/IDIV
genregs(cdb,0xF7,opr,reg); // OPR reg
code_orrex(cdb.last(),rex);
resreg = (op == OPmodass) ? DX : AX; // result register
}
cs.Iop = 0x89 ^ isbyte;
code_newreg(&cs,resreg);
Expand All @@ -1851,11 +1843,7 @@ void cddivass(ref CodeBuilder cdb,elem *e,regm_t *pretregs)

assert(sz == 2 * REGSIZE);

lib = (uns) ? CLIB.uldiv : CLIB.ldiv;
if (op == OPmodass)
lib++;

retregs = mCX | mBX;
regm_t retregs = mCX | mBX;
codelem(cdb,e2,&retregs,false);
getlvalue(cdb,&cs,e1,mDX|mAX | mCX|mBX);
getregs(cdb,mDX | mAX);
Expand All @@ -1868,13 +1856,18 @@ void cddivass(ref CodeBuilder cdb,elem *e,regm_t *pretregs)
retregs = mDX | mAX;
if (op == OPmodass)
retregs = mBX | mCX;

uint lib = uns ? CLIB.uldiv : CLIB.ldiv;
if (op == OPmodass)
++lib;
callclib(cdb,e,lib,&retregs,idxregm(&cs));
reg = findreglsw(retregs);

reg_t reglsw = findreglsw(retregs);
cs.Iop = 0x89;
NEWREG(cs.Irm,reg);
NEWREG(cs.Irm,reglsw);
cdb.gen(&cs); // MOV EA,lsreg
reg = findregmsw(retregs);
NEWREG(cs.Irm,reg);
reg_t regmsw = findregmsw(retregs);
NEWREG(cs.Irm,regmsw);
getlvalue_msw(&cs);
cdb.gen(&cs); // MOV EA+2,msreg
if (e1.Ecount) // if we gen a CSE
Expand Down

0 comments on commit 59c008e

Please sign in to comment.