mirror of
https://github.com/dlang/dmd.git
synced 2025-04-27 21:51:03 +03:00
update getlvalue() with ref parameter
This commit is contained in:
parent
1cdf7e2505
commit
179e8d68eb
6 changed files with 138 additions and 138 deletions
|
@ -100,7 +100,7 @@ private void getlvalue87(ref CodeBuilder cdb, ref code pcs,elem *e,regm_t keepms
|
||||||
if (e.Eoper == OPvar || e.Eoper == OPrelconst)
|
if (e.Eoper == OPvar || e.Eoper == OPrelconst)
|
||||||
e.Vsym.Sflags &= ~GTregcand;
|
e.Vsym.Sflags &= ~GTregcand;
|
||||||
|
|
||||||
getlvalue(cdb, &pcs, e, keepmsk);
|
getlvalue(cdb, pcs, e, keepmsk);
|
||||||
if (ADDFWAIT())
|
if (ADDFWAIT())
|
||||||
pcs.Iflags |= CFwait;
|
pcs.Iflags |= CFwait;
|
||||||
if (I32)
|
if (I32)
|
||||||
|
|
|
@ -310,12 +310,12 @@ void xmmeq(ref CodeBuilder cdb, elem *e, opcode_t op, elem *e1, elem *e2,regm_t
|
||||||
postinc = e11.E2.Vint;
|
postinc = e11.E2.Vint;
|
||||||
if (e11.Eoper == OPpostdec)
|
if (e11.Eoper == OPpostdec)
|
||||||
postinc = -postinc;
|
postinc = -postinc;
|
||||||
getlvalue(cdb,&cs,e11,RMstore | retregs);
|
getlvalue(cdb,cs,e11,RMstore | retregs);
|
||||||
freenode(e11.E2);
|
freenode(e11.E2);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{ postinc = 0;
|
{ postinc = 0;
|
||||||
getlvalue(cdb,&cs,e1,RMstore | retregs); // get lvalue (cl == CNIL if regvar)
|
getlvalue(cdb,cs,e1,RMstore | retregs); // get lvalue (cl == CNIL if regvar)
|
||||||
}
|
}
|
||||||
|
|
||||||
getregs_imm(cdb,regvar ? varregm : 0);
|
getregs_imm(cdb,regvar ? varregm : 0);
|
||||||
|
@ -561,7 +561,7 @@ void xmmopass(ref CodeBuilder cdb,elem *e,regm_t *pretregs)
|
||||||
|
|
||||||
if (!regvar)
|
if (!regvar)
|
||||||
{
|
{
|
||||||
getlvalue(cdb,&cs,e1,rretregs); // get EA
|
getlvalue(cdb,cs,e1,rretregs); // get EA
|
||||||
retregs = *pretregs & XMMREGS & ~rretregs;
|
retregs = *pretregs & XMMREGS & ~rretregs;
|
||||||
if (!retregs)
|
if (!retregs)
|
||||||
retregs = XMMREGS & ~rretregs;
|
retregs = XMMREGS & ~rretregs;
|
||||||
|
@ -630,7 +630,7 @@ void xmmpost(ref CodeBuilder cdb,elem *e,regm_t *pretregs)
|
||||||
code cs;
|
code cs;
|
||||||
if (!regvar)
|
if (!regvar)
|
||||||
{
|
{
|
||||||
getlvalue(cdb,&cs,e1,0); // get EA
|
getlvalue(cdb,cs,e1,0); // get EA
|
||||||
retregs = XMMREGS & ~*pretregs;
|
retregs = XMMREGS & ~*pretregs;
|
||||||
if (!retregs)
|
if (!retregs)
|
||||||
retregs = XMMREGS;
|
retregs = XMMREGS;
|
||||||
|
@ -1276,7 +1276,7 @@ static if (0)
|
||||||
|
|
||||||
if ((op1.Eoper == OPind && !op1.Ecount) || op1.Eoper == OPvar)
|
if ((op1.Eoper == OPind && !op1.Ecount) || op1.Eoper == OPvar)
|
||||||
{
|
{
|
||||||
getlvalue(cdb,&cs, op1, RMload); // get addressing mode
|
getlvalue(cdb,cs, op1, RMload); // get addressing mode
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -1323,7 +1323,7 @@ static if (0)
|
||||||
|
|
||||||
if (((op2.Eoper == OPind && !op2.Ecount) || op2.Eoper == OPvar) && !isMOVHLPS)
|
if (((op2.Eoper == OPind && !op2.Ecount) || op2.Eoper == OPvar) && !isMOVHLPS)
|
||||||
{
|
{
|
||||||
getlvalue(cdb,&cs, op2, RMload | retregs); // get addressing mode
|
getlvalue(cdb,cs, op2, RMload | retregs); // get addressing mode
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -1424,7 +1424,7 @@ static if (0)
|
||||||
{
|
{
|
||||||
if ((e1.Eoper == OPind && !e1.Ecount) || e1.Eoper == OPvar)
|
if ((e1.Eoper == OPind && !e1.Ecount) || e1.Eoper == OPvar)
|
||||||
{
|
{
|
||||||
cr = getlvalue(&cs, e1, RMload | retregs); // get addressing mode
|
cr = getlvalue(cs, e1, RMload | retregs); // get addressing mode
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -1477,7 +1477,7 @@ static if (0)
|
||||||
if (config.avx && e1.Eoper == OPind && !e1.Ecount)
|
if (config.avx && e1.Eoper == OPind && !e1.Ecount)
|
||||||
{
|
{
|
||||||
// VBROADCASTSS X/YMM,MEM
|
// VBROADCASTSS X/YMM,MEM
|
||||||
getlvalue(cdb,&cs, e1, 0); // get addressing mode
|
getlvalue(cdb,cs, e1, 0); // get addressing mode
|
||||||
assert((cs.Irm & 0xC0) != 0xC0); // AVX1 doesn't have register source operands
|
assert((cs.Irm & 0xC0) != 0xC0); // AVX1 doesn't have register source operands
|
||||||
const reg = allocreg(cdb,retregs,ty);
|
const reg = allocreg(cdb,retregs,ty);
|
||||||
cs.Iop = VBROADCASTSS;
|
cs.Iop = VBROADCASTSS;
|
||||||
|
@ -1517,7 +1517,7 @@ static if (0)
|
||||||
if (config.avx && tysize(ty) == 32 && e1.Eoper == OPind && !e1.Ecount)
|
if (config.avx && tysize(ty) == 32 && e1.Eoper == OPind && !e1.Ecount)
|
||||||
{
|
{
|
||||||
// VBROADCASTSD YMM,MEM
|
// VBROADCASTSD YMM,MEM
|
||||||
getlvalue(cdb,&cs, e1, 0); // get addressing mode
|
getlvalue(cdb,cs, e1, 0); // get addressing mode
|
||||||
assert((cs.Irm & 0xC0) != 0xC0); // AVX1 doesn't have register source operands
|
assert((cs.Irm & 0xC0) != 0xC0); // AVX1 doesn't have register source operands
|
||||||
const reg = allocreg(cdb,retregs,ty);
|
const reg = allocreg(cdb,retregs,ty);
|
||||||
cs.Iop = VBROADCASTSD;
|
cs.Iop = VBROADCASTSD;
|
||||||
|
@ -1559,7 +1559,7 @@ static if (0)
|
||||||
if (config.avx >= 2 && e1.Eoper == OPind && !e1.Ecount)
|
if (config.avx >= 2 && e1.Eoper == OPind && !e1.Ecount)
|
||||||
{
|
{
|
||||||
// VPBROADCASTB X/YMM,MEM
|
// VPBROADCASTB X/YMM,MEM
|
||||||
getlvalue(cdb,&cs, e1, 0); // get addressing mode
|
getlvalue(cdb,cs, e1, 0); // get addressing mode
|
||||||
assert((cs.Irm & 0xC0) != 0xC0); // AVX1 doesn't have register source operands
|
assert((cs.Irm & 0xC0) != 0xC0); // AVX1 doesn't have register source operands
|
||||||
reg_t reg = allocreg(cdb,retregs,ty);
|
reg_t reg = allocreg(cdb,retregs,ty);
|
||||||
cs.Iop = VPBROADCASTB;
|
cs.Iop = VPBROADCASTB;
|
||||||
|
@ -1625,7 +1625,7 @@ static if (0)
|
||||||
if (config.avx >= 2 && e1.Eoper == OPind && !e1.Ecount)
|
if (config.avx >= 2 && e1.Eoper == OPind && !e1.Ecount)
|
||||||
{
|
{
|
||||||
// VPBROADCASTW X/YMM,MEM
|
// VPBROADCASTW X/YMM,MEM
|
||||||
getlvalue(cdb,&cs, e1, 0); // get addressing mode
|
getlvalue(cdb,cs, e1, 0); // get addressing mode
|
||||||
assert((cs.Irm & 0xC0) != 0xC0); // AVX1 doesn't have register source operands
|
assert((cs.Irm & 0xC0) != 0xC0); // AVX1 doesn't have register source operands
|
||||||
reg_t reg = allocreg(cdb,retregs,ty);
|
reg_t reg = allocreg(cdb,retregs,ty);
|
||||||
cs.Iop = VPBROADCASTW;
|
cs.Iop = VPBROADCASTW;
|
||||||
|
@ -1677,7 +1677,7 @@ static if (0)
|
||||||
if (config.avx && e1.Eoper == OPind && !e1.Ecount)
|
if (config.avx && e1.Eoper == OPind && !e1.Ecount)
|
||||||
{
|
{
|
||||||
// VPBROADCASTD/VBROADCASTSS X/YMM,MEM
|
// VPBROADCASTD/VBROADCASTSS X/YMM,MEM
|
||||||
getlvalue(cdb,&cs, e1, 0); // get addressing mode
|
getlvalue(cdb,cs, e1, 0); // get addressing mode
|
||||||
assert((cs.Irm & 0xC0) != 0xC0); // AVX1 doesn't have register source operands
|
assert((cs.Irm & 0xC0) != 0xC0); // AVX1 doesn't have register source operands
|
||||||
reg_t reg = allocreg(cdb,retregs,ty);
|
reg_t reg = allocreg(cdb,retregs,ty);
|
||||||
cs.Iop = config.avx >= 2 ? VPBROADCASTD : VBROADCASTSS;
|
cs.Iop = config.avx >= 2 ? VPBROADCASTD : VBROADCASTSS;
|
||||||
|
@ -1719,7 +1719,7 @@ static if (0)
|
||||||
if (e1.Eoper == OPind && !e1.Ecount)
|
if (e1.Eoper == OPind && !e1.Ecount)
|
||||||
{
|
{
|
||||||
// VPBROADCASTQ/VBROADCASTSD/(V)PUNPCKLQDQ X/YMM,MEM
|
// VPBROADCASTQ/VBROADCASTSD/(V)PUNPCKLQDQ X/YMM,MEM
|
||||||
getlvalue(cdb,&cs, e1, 0); // get addressing mode
|
getlvalue(cdb,cs, e1, 0); // get addressing mode
|
||||||
assert((cs.Irm & 0xC0) != 0xC0); // AVX1 doesn't have register source operands
|
assert((cs.Irm & 0xC0) != 0xC0); // AVX1 doesn't have register source operands
|
||||||
reg_t reg = allocreg(cdb,retregs,ty);
|
reg_t reg = allocreg(cdb,retregs,ty);
|
||||||
cs.Iop = config.avx >= 2 ? VPBROADCASTQ : tysize(ty) == 32 ? VBROADCASTSD : PUNPCKLQDQ;
|
cs.Iop = config.avx >= 2 ? VPBROADCASTQ : tysize(ty) == 32 ? VBROADCASTSD : PUNPCKLQDQ;
|
||||||
|
|
|
@ -696,9 +696,9 @@ void loadea(ref CodeBuilder cdb,elem *e,code *cs,uint op,uint reg,targ_size_t of
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
getlvalue(cdb, cs, e, keepmsk);
|
getlvalue(cdb, *cs, e, keepmsk);
|
||||||
if (offset == REGSIZE)
|
if (offset == REGSIZE)
|
||||||
getlvalue_msw(cs);
|
getlvalue_msw(*cs);
|
||||||
else
|
else
|
||||||
cs.IEV1.Voffset += offset;
|
cs.IEV1.Voffset += offset;
|
||||||
if (I64)
|
if (I64)
|
||||||
|
@ -798,7 +798,7 @@ uint getaddrmode(regm_t idxregs)
|
||||||
return mode;
|
return mode;
|
||||||
}
|
}
|
||||||
|
|
||||||
void setaddrmode(code *c, regm_t idxregs)
|
void setaddrmode(ref code c, regm_t idxregs)
|
||||||
{
|
{
|
||||||
uint mode = getaddrmode(idxregs);
|
uint mode = getaddrmode(idxregs);
|
||||||
c.Irm = mode & 0xFF;
|
c.Irm = mode & 0xFF;
|
||||||
|
@ -811,7 +811,7 @@ void setaddrmode(code *c, regm_t idxregs)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@trusted
|
@trusted
|
||||||
void getlvalue_msw(code *c)
|
void getlvalue_msw(ref code c)
|
||||||
{
|
{
|
||||||
if (c.IFL1 == FLreg)
|
if (c.IFL1 == FLreg)
|
||||||
{
|
{
|
||||||
|
@ -830,7 +830,7 @@ void getlvalue_msw(code *c)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@trusted
|
@trusted
|
||||||
void getlvalue_lsw(code *c)
|
void getlvalue_lsw(ref code c)
|
||||||
{
|
{
|
||||||
if (c.IFL1 == FLreg)
|
if (c.IFL1 == FLreg)
|
||||||
{
|
{
|
||||||
|
@ -847,19 +847,19 @@ void getlvalue_lsw(code *c)
|
||||||
|
|
||||||
/******************
|
/******************
|
||||||
* Compute addressing mode.
|
* Compute addressing mode.
|
||||||
* Generate & return sequence of code (if any).
|
|
||||||
* Return in cs the info on it.
|
* Return in cs the info on it.
|
||||||
* Input:
|
* Params:
|
||||||
* pcs -> where to store data about addressing mode
|
* cdb = sink for any code generated
|
||||||
* e -> the lvalue elem
|
* pcs = set to addressing mode
|
||||||
* keepmsk mask of registers we must not destroy or use
|
* e = the lvalue elem
|
||||||
|
* keepmsk = mask of registers we must not destroy or use
|
||||||
* if (keepmsk & RMstore), this will be only a store operation
|
* if (keepmsk & RMstore), this will be only a store operation
|
||||||
* into the lvalue
|
* into the lvalue
|
||||||
* if (keepmsk & RMload), this will be a read operation only
|
* if (keepmsk & RMload), this will be a read operation only
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@trusted
|
@trusted
|
||||||
void getlvalue(ref CodeBuilder cdb,code *pcs,elem *e,regm_t keepmsk)
|
void getlvalue(ref CodeBuilder cdb,ref code pcs,elem *e,regm_t keepmsk)
|
||||||
{
|
{
|
||||||
FL fl;
|
FL fl;
|
||||||
uint f, opsave;
|
uint f, opsave;
|
||||||
|
@ -1161,12 +1161,12 @@ void getlvalue(ref CodeBuilder cdb,code *pcs,elem *e,regm_t keepmsk)
|
||||||
flagsave = pcs.Iflags;
|
flagsave = pcs.Iflags;
|
||||||
ubyte rexsave = pcs.Irex;
|
ubyte rexsave = pcs.Irex;
|
||||||
pcs.Iop = LEA;
|
pcs.Iop = LEA;
|
||||||
code_newreg(pcs, reg);
|
code_newreg(&pcs, reg);
|
||||||
if (!I16)
|
if (!I16)
|
||||||
pcs.Iflags &= ~CFopsize;
|
pcs.Iflags &= ~CFopsize;
|
||||||
if (I64)
|
if (I64)
|
||||||
pcs.Irex |= REX_W;
|
pcs.Irex |= REX_W;
|
||||||
cdb.gen(pcs); // LEA idxreg,EA
|
cdb.gen(&pcs); // LEA idxreg,EA
|
||||||
cssave(e1,idxregs,true);
|
cssave(e1,idxregs,true);
|
||||||
if (!I16)
|
if (!I16)
|
||||||
{
|
{
|
||||||
|
@ -4682,7 +4682,7 @@ void pushParams(ref CodeBuilder cdb, elem* e, uint stackalign, tym_t tyf)
|
||||||
cs.IEV1.Voffset -= REGSIZE;
|
cs.IEV1.Voffset -= REGSIZE;
|
||||||
cdb.gen(&cs); // PUSH EA+4
|
cdb.gen(&cs); // PUSH EA+4
|
||||||
cdb.genadjesp(REGSIZE);
|
cdb.genadjesp(REGSIZE);
|
||||||
getlvalue_lsw(&cs);
|
getlvalue_lsw(cs);
|
||||||
cdb.gen(&cs); // PUSH EA+2
|
cdb.gen(&cs); // PUSH EA+2
|
||||||
}
|
}
|
||||||
else /* TYlong */
|
else /* TYlong */
|
||||||
|
@ -4690,7 +4690,7 @@ void pushParams(ref CodeBuilder cdb, elem* e, uint stackalign, tym_t tyf)
|
||||||
cdb.genadjesp(REGSIZE);
|
cdb.genadjesp(REGSIZE);
|
||||||
}
|
}
|
||||||
cgstate.stackpush += sz;
|
cgstate.stackpush += sz;
|
||||||
getlvalue_lsw(&cs);
|
getlvalue_lsw(cs);
|
||||||
cdb.gen(&cs); // PUSH EA
|
cdb.gen(&cs); // PUSH EA
|
||||||
cdb.genadjesp(REGSIZE);
|
cdb.genadjesp(REGSIZE);
|
||||||
freenode(e);
|
freenode(e);
|
||||||
|
|
|
@ -284,7 +284,7 @@ void cdorth(ref CGstate cg, ref CodeBuilder cdb,elem *e,regm_t *pretregs)
|
||||||
code cs = void;
|
code cs = void;
|
||||||
cs.Iflags = 0;
|
cs.Iflags = 0;
|
||||||
cs.Irex = 0;
|
cs.Irex = 0;
|
||||||
getlvalue(cdb,&cs,e1,0);
|
getlvalue(cdb,cs,e1,0);
|
||||||
targ_size_t value = e2.Vpointer;
|
targ_size_t value = e2.Vpointer;
|
||||||
if (sz == 2)
|
if (sz == 2)
|
||||||
value &= 0xFFFF;
|
value &= 0xFFFF;
|
||||||
|
@ -323,7 +323,7 @@ void cdorth(ref CGstate cg, ref CodeBuilder cdb,elem *e,regm_t *pretregs)
|
||||||
code cs = void;
|
code cs = void;
|
||||||
cs.Iflags = 0;
|
cs.Iflags = 0;
|
||||||
cs.Irex = 0;
|
cs.Irex = 0;
|
||||||
getlvalue(cdb,&cs,e1,0);
|
getlvalue(cdb,cs,e1,0);
|
||||||
code_newreg(&cs, reg);
|
code_newreg(&cs, reg);
|
||||||
if (I64 && isbyte && reg >= 4)
|
if (I64 && isbyte && reg >= 4)
|
||||||
cs.Irex |= REX;
|
cs.Irex |= REX;
|
||||||
|
@ -367,7 +367,7 @@ void cdorth(ref CGstate cg, ref CodeBuilder cdb,elem *e,regm_t *pretregs)
|
||||||
const inc = e.Ecount != 0;
|
const inc = e.Ecount != 0;
|
||||||
nest += inc;
|
nest += inc;
|
||||||
code csx = void;
|
code csx = void;
|
||||||
getlvalue(cdb,&csx,e,0);
|
getlvalue(cdb,csx,e,0);
|
||||||
nest -= inc;
|
nest -= inc;
|
||||||
const regx = allocreg(cdb,*pretregs,ty);
|
const regx = allocreg(cdb,*pretregs,ty);
|
||||||
csx.Iop = LEA;
|
csx.Iop = LEA;
|
||||||
|
@ -844,7 +844,7 @@ void cdorth(ref CGstate cg, ref CodeBuilder cdb,elem *e,regm_t *pretregs)
|
||||||
code_orflag(cdb.last(),CFpsw);
|
code_orflag(cdb.last(),CFpsw);
|
||||||
reg = findregmsw(retregs);
|
reg = findregmsw(retregs);
|
||||||
if (!OTleaf(e2.Eoper))
|
if (!OTleaf(e2.Eoper))
|
||||||
{ getlvalue_msw(&cs);
|
{ getlvalue_msw(cs);
|
||||||
cs.Iop = op2;
|
cs.Iop = op2;
|
||||||
NEWREG(cs.Irm,reg);
|
NEWREG(cs.Irm,reg);
|
||||||
cdb.gen(&cs); // ADC reg,data+2
|
cdb.gen(&cs); // ADC reg,data+2
|
||||||
|
@ -1238,7 +1238,7 @@ void cdmul(ref CGstate cg, ref CodeBuilder cdb,elem *e,regm_t *pretregs)
|
||||||
if ((cs.Irm & 0xC0) == 0xC0) // if EA is a register
|
if ((cs.Irm & 0xC0) == 0xC0) // if EA is a register
|
||||||
loadea(cdb,e2,&cs,0xF7,4,0,mAX | mskl(reg),mAX | mDX); // MUL EA
|
loadea(cdb,e2,&cs,0xF7,4,0,mAX | mskl(reg),mAX | mDX); // MUL EA
|
||||||
else
|
else
|
||||||
{ getlvalue_lsw(&cs);
|
{ getlvalue_lsw(cs);
|
||||||
cdb.gen(&cs); // MUL EA
|
cdb.gen(&cs); // MUL EA
|
||||||
}
|
}
|
||||||
cdb.gen2(0x03,modregrm(3,DX,reg)); // ADD DX,reg
|
cdb.gen2(0x03,modregrm(3,DX,reg)); // ADD DX,reg
|
||||||
|
@ -2008,7 +2008,7 @@ void cdnot(ref CGstate cg, ref CodeBuilder cdb,elem *e,regm_t *pretregs)
|
||||||
if (sz <= REGSIZE && e1.Eoper == OPvar)
|
if (sz <= REGSIZE && e1.Eoper == OPvar)
|
||||||
{ code cs;
|
{ code cs;
|
||||||
|
|
||||||
getlvalue(cdb,&cs,e1,0);
|
getlvalue(cdb,cs,e1,0);
|
||||||
freenode(e1);
|
freenode(e1);
|
||||||
if (!I16 && sz == 2)
|
if (!I16 && sz == 2)
|
||||||
cs.Iflags |= CFopsize;
|
cs.Iflags |= CFopsize;
|
||||||
|
@ -3249,7 +3249,7 @@ void cdind(ref CGstate cg, ref CodeBuilder cdb,elem *e,regm_t *pretregs)
|
||||||
|
|
||||||
code cs;
|
code cs;
|
||||||
|
|
||||||
getlvalue(cdb,&cs,e,RMload); // get addressing mode
|
getlvalue(cdb,cs,e,RMload); // get addressing mode
|
||||||
//printf("Irex = %02x, Irm = x%02x, Isib = x%02x\n", cs.Irex, cs.Irm, cs.Isib);
|
//printf("Irex = %02x, Irm = x%02x, Isib = x%02x\n", cs.Irex, cs.Irm, cs.Isib);
|
||||||
//fprintf(stderr,"cd2 :\n"); WRcodlst(c);
|
//fprintf(stderr,"cd2 :\n"); WRcodlst(c);
|
||||||
if (*pretregs == 0)
|
if (*pretregs == 0)
|
||||||
|
@ -3288,7 +3288,7 @@ void cdind(ref CGstate cg, ref CodeBuilder cdb,elem *e,regm_t *pretregs)
|
||||||
reg = allocreg(cdb,retregs,TYint);
|
reg = allocreg(cdb,retregs,TYint);
|
||||||
cs.Iop = MOVZXw;
|
cs.Iop = MOVZXw;
|
||||||
cs.Irm |= modregrm(0,reg,0);
|
cs.Irm |= modregrm(0,reg,0);
|
||||||
getlvalue_msw(&cs);
|
getlvalue_msw(cs);
|
||||||
cdb.gen(&cs); // MOVZX reg,msw
|
cdb.gen(&cs); // MOVZX reg,msw
|
||||||
goto L4;
|
goto L4;
|
||||||
}
|
}
|
||||||
|
@ -3298,7 +3298,7 @@ void cdind(ref CGstate cg, ref CodeBuilder cdb,elem *e,regm_t *pretregs)
|
||||||
reg = allocreg(cdb,retregs,TYint);
|
reg = allocreg(cdb,retregs,TYint);
|
||||||
cs.Iop = 0x8B;
|
cs.Iop = 0x8B;
|
||||||
code_newreg(&cs,reg);
|
code_newreg(&cs,reg);
|
||||||
getlvalue_msw(&cs);
|
getlvalue_msw(cs);
|
||||||
cdb.gen(&cs); // MOV reg,msw
|
cdb.gen(&cs); // MOV reg,msw
|
||||||
if (I32)
|
if (I32)
|
||||||
{ if (tym == TYdouble || tym == TYdouble_alias)
|
{ if (tym == TYdouble || tym == TYdouble_alias)
|
||||||
|
@ -3308,7 +3308,7 @@ void cdind(ref CGstate cg, ref CodeBuilder cdb,elem *e,regm_t *pretregs)
|
||||||
cdb.gen2(0xD1,modregrm(3,4,reg)); // SHL reg,1
|
cdb.gen2(0xD1,modregrm(3,4,reg)); // SHL reg,1
|
||||||
L4:
|
L4:
|
||||||
cs.Iop = 0x0B;
|
cs.Iop = 0x0B;
|
||||||
getlvalue_lsw(&cs);
|
getlvalue_lsw(cs);
|
||||||
cs.Iflags |= CFpsw;
|
cs.Iflags |= CFpsw;
|
||||||
cdb.gen(&cs); // OR reg,lsw
|
cdb.gen(&cs); // OR reg,lsw
|
||||||
}
|
}
|
||||||
|
@ -3435,16 +3435,16 @@ void cdind(ref CGstate cg, ref CodeBuilder cdb,elem *e,regm_t *pretregs)
|
||||||
if (sz == REGSIZE + 2)
|
if (sz == REGSIZE + 2)
|
||||||
cs.Iflags |= CFopsize;
|
cs.Iflags |= CFopsize;
|
||||||
lsreg = reg;
|
lsreg = reg;
|
||||||
getlvalue_msw(&cs); // MOV reg,msw
|
getlvalue_msw(cs); // MOV reg,msw
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
code_newreg(&cs,reg);
|
code_newreg(&cs,reg);
|
||||||
getlvalue_msw(&cs);
|
getlvalue_msw(cs);
|
||||||
cdb.gen(&cs); // MOV reg,msw
|
cdb.gen(&cs); // MOV reg,msw
|
||||||
if (sz == REGSIZE + 2)
|
if (sz == REGSIZE + 2)
|
||||||
cdb.last().Iflags |= CFopsize;
|
cdb.last().Iflags |= CFopsize;
|
||||||
getlvalue_lsw(&cs); // MOV lsreg,lsw
|
getlvalue_lsw(cs); // MOV lsreg,lsw
|
||||||
}
|
}
|
||||||
NEWREG(cs.Irm,lsreg);
|
NEWREG(cs.Irm,lsreg);
|
||||||
cdb.gen(&cs);
|
cdb.gen(&cs);
|
||||||
|
@ -3453,11 +3453,11 @@ void cdind(ref CGstate cg, ref CodeBuilder cdb,elem *e,regm_t *pretregs)
|
||||||
{
|
{
|
||||||
// Index registers are always the lsw!
|
// Index registers are always the lsw!
|
||||||
cs.Irm |= modregrm(0,reg,0);
|
cs.Irm |= modregrm(0,reg,0);
|
||||||
getlvalue_msw(&cs);
|
getlvalue_msw(cs);
|
||||||
cdb.gen(&cs); // MOV reg,msw
|
cdb.gen(&cs); // MOV reg,msw
|
||||||
lsreg = findreglsw(retregs);
|
lsreg = findreglsw(retregs);
|
||||||
NEWREG(cs.Irm,lsreg);
|
NEWREG(cs.Irm,lsreg);
|
||||||
getlvalue_lsw(&cs); // MOV lsreg,lsw
|
getlvalue_lsw(cs); // MOV lsreg,lsw
|
||||||
cdb.gen(&cs);
|
cdb.gen(&cs);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5196,7 +5196,7 @@ void cdpost(ref CGstate cg, ref CodeBuilder cdb,elem *e,regm_t *pretregs)
|
||||||
if (config.exe & EX_windos)
|
if (config.exe & EX_windos)
|
||||||
{
|
{
|
||||||
assert(sz <= 8);
|
assert(sz <= 8);
|
||||||
getlvalue(cdb,&cs,e.E1,DOUBLEREGS);
|
getlvalue(cdb,cs,e.E1,DOUBLEREGS);
|
||||||
freenode(e.E1);
|
freenode(e.E1);
|
||||||
regm_t idxregs = idxregm(&cs); // mask of index regs used
|
regm_t idxregs = idxregm(&cs); // mask of index regs used
|
||||||
cs.Iop = 0x8B; /* MOV DOUBLEREGS,EA */
|
cs.Iop = 0x8B; /* MOV DOUBLEREGS,EA */
|
||||||
|
@ -5300,7 +5300,7 @@ if (config.exe & EX_windos)
|
||||||
assert(e2.Eoper == OPconst);
|
assert(e2.Eoper == OPconst);
|
||||||
uint isbyte = (sz == 1);
|
uint isbyte = (sz == 1);
|
||||||
regm_t possregs = isbyte ? BYTEREGS : cgstate.allregs;
|
regm_t possregs = isbyte ? BYTEREGS : cgstate.allregs;
|
||||||
getlvalue(cdb,&cs,e.E1,0);
|
getlvalue(cdb,cs,e.E1,0);
|
||||||
freenode(e.E1);
|
freenode(e.E1);
|
||||||
regm_t idxregs = idxregm(&cs); // mask of index regs used
|
regm_t idxregs = idxregm(&cs); // mask of index regs used
|
||||||
if (sz <= REGSIZE && *pretregs == mPSW && (cs.Irm & 0xC0) == 0xC0 &&
|
if (sz <= REGSIZE && *pretregs == mPSW && (cs.Irm & 0xC0) == 0xC0 &&
|
||||||
|
@ -5433,7 +5433,7 @@ if (config.exe & EX_windos)
|
||||||
{
|
{
|
||||||
reg_t preg;
|
reg_t preg;
|
||||||
|
|
||||||
getlvalue_msw(&cs);
|
getlvalue_msw(cs);
|
||||||
if (*pretregs & mES)
|
if (*pretregs & mES)
|
||||||
{
|
{
|
||||||
preg = ES;
|
preg = ES;
|
||||||
|
@ -5491,9 +5491,9 @@ if (config.exe & EX_windos)
|
||||||
cs.Irm |= modregrm(0,lreg,0);
|
cs.Irm |= modregrm(0,lreg,0);
|
||||||
cdb.gen(&cs); // MOV lreg,EA
|
cdb.gen(&cs); // MOV lreg,EA
|
||||||
NEWREG(cs.Irm,DX);
|
NEWREG(cs.Irm,DX);
|
||||||
getlvalue_msw(&cs);
|
getlvalue_msw(cs);
|
||||||
cdb.gen(&cs); // MOV DX,EA+2
|
cdb.gen(&cs); // MOV DX,EA+2
|
||||||
getlvalue_lsw(&cs);
|
getlvalue_lsw(cs);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Allocate temporary register, rtmp
|
// Allocate temporary register, rtmp
|
||||||
|
@ -5513,7 +5513,7 @@ if (config.exe & EX_windos)
|
||||||
cdb.gen2(0xD3,modregrm(3,4,rtmp)); // SHL rtmp,CL
|
cdb.gen2(0xD3,modregrm(3,4,rtmp)); // SHL rtmp,CL
|
||||||
cs.Iop = 0x01;
|
cs.Iop = 0x01;
|
||||||
NEWREG(cs.Irm,rtmp); // ADD EA+2,rtmp
|
NEWREG(cs.Irm,rtmp); // ADD EA+2,rtmp
|
||||||
getlvalue_msw(&cs);
|
getlvalue_msw(cs);
|
||||||
cdb.gen(&cs);
|
cdb.gen(&cs);
|
||||||
fixresult(cdb,e,retregs,*pretregs);
|
fixresult(cdb,e,retregs,*pretregs);
|
||||||
return;
|
return;
|
||||||
|
@ -5532,18 +5532,18 @@ if (config.exe & EX_windos)
|
||||||
cs.Irm |= modregrm(0,sreg,0);
|
cs.Irm |= modregrm(0,sreg,0);
|
||||||
cdb.gen(&cs); // MOV sreg,EA
|
cdb.gen(&cs); // MOV sreg,EA
|
||||||
NEWREG(cs.Irm,reg);
|
NEWREG(cs.Irm,reg);
|
||||||
getlvalue_msw(&cs);
|
getlvalue_msw(cs);
|
||||||
cdb.gen(&cs); // MOV reg,EA+2
|
cdb.gen(&cs); // MOV reg,EA+2
|
||||||
cs.Iop = 0x81;
|
cs.Iop = 0x81;
|
||||||
cs.Irm &= ~cast(int)modregrm(0,7,0); /* reg field = 0 for ADD */
|
cs.Irm &= ~cast(int)modregrm(0,7,0); /* reg field = 0 for ADD */
|
||||||
if (op == OPpostdec)
|
if (op == OPpostdec)
|
||||||
cs.Irm |= modregrm(0,5,0); /* SUB */
|
cs.Irm |= modregrm(0,5,0); /* SUB */
|
||||||
getlvalue_lsw(&cs);
|
getlvalue_lsw(cs);
|
||||||
cs.IFL2 = FLconst;
|
cs.IFL2 = FLconst;
|
||||||
cs.IEV2.Vlong = e2.Vlong;
|
cs.IEV2.Vlong = e2.Vlong;
|
||||||
cdb.gen(&cs); // ADD/SUB EA,const
|
cdb.gen(&cs); // ADD/SUB EA,const
|
||||||
code_orflag(cdb.last(),CFpsw);
|
code_orflag(cdb.last(),CFpsw);
|
||||||
getlvalue_msw(&cs);
|
getlvalue_msw(cs);
|
||||||
cs.IEV2.Vlong = 0;
|
cs.IEV2.Vlong = 0;
|
||||||
if (op == OPpostinc)
|
if (op == OPpostinc)
|
||||||
cs.Irm ^= modregrm(0,2,0); /* ADC */
|
cs.Irm ^= modregrm(0,2,0); /* ADC */
|
||||||
|
|
|
@ -2349,7 +2349,7 @@ L1:
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@trusted
|
@trusted
|
||||||
void cod3_ptrchk(ref CodeBuilder cdb,code *pcs,regm_t keepmsk)
|
void cod3_ptrchk(ref CodeBuilder cdb,ref code pcs,regm_t keepmsk)
|
||||||
{
|
{
|
||||||
ubyte sib;
|
ubyte sib;
|
||||||
reg_t reg;
|
reg_t reg;
|
||||||
|
@ -2384,7 +2384,7 @@ void cod3_ptrchk(ref CodeBuilder cdb,code *pcs,regm_t keepmsk)
|
||||||
pcs.Iop = LEA;
|
pcs.Iop = LEA;
|
||||||
pcs.Irm |= modregrm(0,reg,0);
|
pcs.Irm |= modregrm(0,reg,0);
|
||||||
pcs.Iflags &= ~(CFopsize | CFss | CFes | CFcs); // no prefix bytes needed
|
pcs.Iflags &= ~(CFopsize | CFss | CFes | CFcs); // no prefix bytes needed
|
||||||
cdb.gen(pcs); // LEA reg,EA
|
cdb.gen(&pcs); // LEA reg,EA
|
||||||
|
|
||||||
pcs.Iflags = flagsave;
|
pcs.Iflags = flagsave;
|
||||||
pcs.Iop = opsave;
|
pcs.Iop = opsave;
|
||||||
|
@ -4593,7 +4593,7 @@ void gen_spill_reg(ref CodeBuilder cdb, Symbol* s, bool toreg)
|
||||||
cs.Iop = xmmload(s.Stype.Tty); // MOVSS/D xreg,mem
|
cs.Iop = xmmload(s.Stype.Tty); // MOVSS/D xreg,mem
|
||||||
else
|
else
|
||||||
cs.Iop = xmmstore(s.Stype.Tty); // MOVSS/D mem,xreg
|
cs.Iop = xmmstore(s.Stype.Tty); // MOVSS/D mem,xreg
|
||||||
getlvalue(cdb,&cs,e,keepmsk);
|
getlvalue(cdb,cs,e,keepmsk);
|
||||||
cs.orReg(s.Sreglsw - XMM0);
|
cs.orReg(s.Sreglsw - XMM0);
|
||||||
cdb.gen(&cs);
|
cdb.gen(&cs);
|
||||||
}
|
}
|
||||||
|
@ -4602,7 +4602,7 @@ void gen_spill_reg(ref CodeBuilder cdb, Symbol* s, bool toreg)
|
||||||
const int sz = cast(int)type_size(s.Stype);
|
const int sz = cast(int)type_size(s.Stype);
|
||||||
cs.Iop = toreg ? 0x8B : 0x89; // MOV reg,mem[ESP] : MOV mem[ESP],reg
|
cs.Iop = toreg ? 0x8B : 0x89; // MOV reg,mem[ESP] : MOV mem[ESP],reg
|
||||||
cs.Iop ^= (sz == 1);
|
cs.Iop ^= (sz == 1);
|
||||||
getlvalue(cdb,&cs,e,keepmsk);
|
getlvalue(cdb,cs,e,keepmsk);
|
||||||
cs.orReg(s.Sreglsw);
|
cs.orReg(s.Sreglsw);
|
||||||
if (I64 && sz == 1 && s.Sreglsw >= 4)
|
if (I64 && sz == 1 && s.Sreglsw >= 4)
|
||||||
cs.Irex |= REX;
|
cs.Irex |= REX;
|
||||||
|
@ -4615,7 +4615,7 @@ void gen_spill_reg(ref CodeBuilder cdb, Symbol* s, bool toreg)
|
||||||
if (sz > REGSIZE)
|
if (sz > REGSIZE)
|
||||||
{
|
{
|
||||||
cs.setReg(s.Sregmsw);
|
cs.setReg(s.Sregmsw);
|
||||||
getlvalue_msw(&cs);
|
getlvalue_msw(cs);
|
||||||
if ((cs.Irm & 0xC0) == 0xC0 && // reg,reg
|
if ((cs.Irm & 0xC0) == 0xC0 && // reg,reg
|
||||||
(((cs.Irm >> 3) ^ cs.Irm) & 7) == 0 && // registers match
|
(((cs.Irm >> 3) ^ cs.Irm) & 7) == 0 && // registers match
|
||||||
(((cs.Irex >> 2) ^ cs.Irex) & 1) == 0) // REX_R and REX_B match
|
(((cs.Irex >> 2) ^ cs.Irex) & 1) == 0) // REX_R and REX_B match
|
||||||
|
|
|
@ -151,7 +151,7 @@ private void opassdbl(ref CodeBuilder cdb,elem *e,regm_t *pretregs,OPER op)
|
||||||
uint clib = clibtab[op - OPpostinc];
|
uint clib = clibtab[op - OPpostinc];
|
||||||
elem *e1 = e.E1;
|
elem *e1 = e.E1;
|
||||||
tym_t tym = tybasic(e1.Ety);
|
tym_t tym = tybasic(e1.Ety);
|
||||||
getlvalue(cdb,&cs,e1,DOUBLEREGS | mBX | mCX);
|
getlvalue(cdb,cs,e1,DOUBLEREGS | mBX | mCX);
|
||||||
|
|
||||||
if (tym == TYfloat)
|
if (tym == TYfloat)
|
||||||
{
|
{
|
||||||
|
@ -166,9 +166,9 @@ private void opassdbl(ref CodeBuilder cdb,elem *e,regm_t *pretregs,OPER op)
|
||||||
if (!I32)
|
if (!I32)
|
||||||
{
|
{
|
||||||
cs.Irm |= modregrm(0,DX,0);
|
cs.Irm |= modregrm(0,DX,0);
|
||||||
getlvalue_msw(&cs);
|
getlvalue_msw(cs);
|
||||||
cdb.gen(&cs);
|
cdb.gen(&cs);
|
||||||
getlvalue_lsw(&cs);
|
getlvalue_lsw(cs);
|
||||||
|
|
||||||
}
|
}
|
||||||
retregs2 = FLOATREGS2;
|
retregs2 = FLOATREGS2;
|
||||||
|
@ -185,9 +185,9 @@ private void opassdbl(ref CodeBuilder cdb,elem *e,regm_t *pretregs,OPER op)
|
||||||
cs.Irm |= modregrm(0,AX,0);
|
cs.Irm |= modregrm(0,AX,0);
|
||||||
cdb.gen(&cs);
|
cdb.gen(&cs);
|
||||||
cs.Irm |= modregrm(0,DX,0);
|
cs.Irm |= modregrm(0,DX,0);
|
||||||
getlvalue_msw(&cs);
|
getlvalue_msw(cs);
|
||||||
cdb.gen(&cs);
|
cdb.gen(&cs);
|
||||||
getlvalue_lsw(&cs);
|
getlvalue_lsw(cs);
|
||||||
|
|
||||||
retregs2 = DOUBLEREGS2_32;
|
retregs2 = DOUBLEREGS2_32;
|
||||||
idxregs = DOUBLEREGS_32 | idxregm(&cs);
|
idxregs = DOUBLEREGS_32 | idxregm(&cs);
|
||||||
|
@ -199,11 +199,11 @@ private void opassdbl(ref CodeBuilder cdb,elem *e,regm_t *pretregs,OPER op)
|
||||||
cs.Irm |= modregrm(0,6,0);
|
cs.Irm |= modregrm(0,6,0);
|
||||||
cs.IEV1.Voffset += DOUBLESIZE - REGSIZE;
|
cs.IEV1.Voffset += DOUBLESIZE - REGSIZE;
|
||||||
cdb.gen(&cs);
|
cdb.gen(&cs);
|
||||||
getlvalue_lsw(&cs);
|
getlvalue_lsw(cs);
|
||||||
cdb.gen(&cs);
|
cdb.gen(&cs);
|
||||||
getlvalue_lsw(&cs);
|
getlvalue_lsw(cs);
|
||||||
cdb.gen(&cs);
|
cdb.gen(&cs);
|
||||||
getlvalue_lsw(&cs);
|
getlvalue_lsw(cs);
|
||||||
cdb.gen(&cs);
|
cdb.gen(&cs);
|
||||||
cgstate.stackpush += DOUBLESIZE;
|
cgstate.stackpush += DOUBLESIZE;
|
||||||
|
|
||||||
|
@ -246,7 +246,7 @@ private void opnegassdbl(ref CodeBuilder cdb,elem *e,regm_t *pretregs)
|
||||||
int sz = _tysize[tym];
|
int sz = _tysize[tym];
|
||||||
code cs;
|
code cs;
|
||||||
|
|
||||||
getlvalue(cdb,&cs,e1,*pretregs ? DOUBLEREGS | mBX | mCX : 0);
|
getlvalue(cdb,cs,e1,*pretregs ? DOUBLEREGS | mBX | mCX : 0);
|
||||||
modEA(cdb,&cs);
|
modEA(cdb,&cs);
|
||||||
cs.Irm |= modregrm(0,6,0);
|
cs.Irm |= modregrm(0,6,0);
|
||||||
cs.Iop = 0x80;
|
cs.Iop = 0x80;
|
||||||
|
@ -276,9 +276,9 @@ private void opnegassdbl(ref CodeBuilder cdb,elem *e,regm_t *pretregs)
|
||||||
if (!I32)
|
if (!I32)
|
||||||
{
|
{
|
||||||
NEWREG(cs.Irm, DX);
|
NEWREG(cs.Irm, DX);
|
||||||
getlvalue_msw(&cs);
|
getlvalue_msw(cs);
|
||||||
cdb.gen(&cs);
|
cdb.gen(&cs);
|
||||||
getlvalue_lsw(&cs);
|
getlvalue_lsw(cs);
|
||||||
|
|
||||||
}
|
}
|
||||||
retregs = FLOATREGS;
|
retregs = FLOATREGS;
|
||||||
|
@ -294,9 +294,9 @@ private void opnegassdbl(ref CodeBuilder cdb,elem *e,regm_t *pretregs)
|
||||||
cs.Irm |= modregrm(0,AX,0);
|
cs.Irm |= modregrm(0,AX,0);
|
||||||
cdb.gen(&cs);
|
cdb.gen(&cs);
|
||||||
cs.Irm |= modregrm(0,DX,0);
|
cs.Irm |= modregrm(0,DX,0);
|
||||||
getlvalue_msw(&cs);
|
getlvalue_msw(cs);
|
||||||
cdb.gen(&cs);
|
cdb.gen(&cs);
|
||||||
getlvalue_lsw(&cs);
|
getlvalue_lsw(cs);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -444,13 +444,13 @@ void cdeq(ref CGstate cg, ref CodeBuilder cdb,elem *e,regm_t *pretregs)
|
||||||
postinc = e11.E2.Vint;
|
postinc = e11.E2.Vint;
|
||||||
if (e11.Eoper == OPpostdec)
|
if (e11.Eoper == OPpostdec)
|
||||||
postinc = -postinc;
|
postinc = -postinc;
|
||||||
getlvalue(cdb,&cs,e1,RMstore);
|
getlvalue(cdb,cs,e1,RMstore);
|
||||||
freenode(e11.E2);
|
freenode(e11.E2);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
postinc = 0;
|
postinc = 0;
|
||||||
getlvalue(cdb,&cs,e1,RMstore);
|
getlvalue(cdb,cs,e1,RMstore);
|
||||||
|
|
||||||
if (e2oper == OPconst &&
|
if (e2oper == OPconst &&
|
||||||
config.flags4 & CFG4speed &&
|
config.flags4 & CFG4speed &&
|
||||||
|
@ -499,7 +499,7 @@ void cdeq(ref CGstate cg, ref CodeBuilder cdb,elem *e,regm_t *pretregs)
|
||||||
cs.Iop = STO;
|
cs.Iop = STO;
|
||||||
cs.Irm |= modregrm(0,regx,0);
|
cs.Irm |= modregrm(0,regx,0);
|
||||||
cdb.gen(&cs);
|
cdb.gen(&cs);
|
||||||
getlvalue_msw(&cs);
|
getlvalue_msw(cs);
|
||||||
cdb.gen(&cs);
|
cdb.gen(&cs);
|
||||||
freenode(e2);
|
freenode(e2);
|
||||||
goto Lp;
|
goto Lp;
|
||||||
|
@ -529,7 +529,7 @@ void cdeq(ref CGstate cg, ref CodeBuilder cdb,elem *e,regm_t *pretregs)
|
||||||
if (sz > REGSIZE)
|
if (sz > REGSIZE)
|
||||||
{
|
{
|
||||||
cs.Iop = 0x8C;
|
cs.Iop = 0x8C;
|
||||||
getlvalue_msw(&cs);
|
getlvalue_msw(cs);
|
||||||
cs.Irm |= modregrm(0,3,0);
|
cs.Irm |= modregrm(0,3,0);
|
||||||
cdb.gen(&cs); // MOV EA+2,DS
|
cdb.gen(&cs); // MOV EA+2,DS
|
||||||
}
|
}
|
||||||
|
@ -552,7 +552,7 @@ void cdeq(ref CGstate cg, ref CodeBuilder cdb,elem *e,regm_t *pretregs)
|
||||||
else
|
else
|
||||||
movregconst(cdb,regx,*p,1 ^ (cs.Iop & 1));
|
movregconst(cdb,regx,*p,1 ^ (cs.Iop & 1));
|
||||||
if (sz == 2 * REGSIZE)
|
if (sz == 2 * REGSIZE)
|
||||||
{ getlvalue_msw(&cs);
|
{ getlvalue_msw(cs);
|
||||||
if (REGSIZE == 2)
|
if (REGSIZE == 2)
|
||||||
movregconst(cdb,cs.Irm & 7,(cast(ushort *)p)[1],0);
|
movregconst(cdb,cs.Irm & 7,(cast(ushort *)p)[1],0);
|
||||||
else if (REGSIZE == 4)
|
else if (REGSIZE == 4)
|
||||||
|
@ -712,13 +712,13 @@ void cdeq(ref CGstate cg, ref CodeBuilder cdb,elem *e,regm_t *pretregs)
|
||||||
postinc = e11.E2.Vint;
|
postinc = e11.E2.Vint;
|
||||||
if (e11.Eoper == OPpostdec)
|
if (e11.Eoper == OPpostdec)
|
||||||
postinc = -postinc;
|
postinc = -postinc;
|
||||||
getlvalue(cdb,&cs,e1,RMstore | retregs);
|
getlvalue(cdb,cs,e1,RMstore | retregs);
|
||||||
freenode(e11.E2);
|
freenode(e11.E2);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
postinc = 0;
|
postinc = 0;
|
||||||
getlvalue(cdb,&cs,e1,RMstore | retregs); // get lvalue (cl == null if regvar)
|
getlvalue(cdb,cs,e1,RMstore | retregs); // get lvalue (cl == null if regvar)
|
||||||
}
|
}
|
||||||
|
|
||||||
getregs(cdb,varregm);
|
getregs(cdb,varregm);
|
||||||
|
@ -729,7 +729,7 @@ void cdeq(ref CGstate cg, ref CodeBuilder cdb,elem *e,regm_t *pretregs)
|
||||||
reg = findreglsw(retregs);
|
reg = findreglsw(retregs);
|
||||||
cs.Irm |= modregrm(0,reg,0);
|
cs.Irm |= modregrm(0,reg,0);
|
||||||
cdb.gen(&cs); // MOV EA,reg
|
cdb.gen(&cs); // MOV EA,reg
|
||||||
getlvalue_msw(&cs); // point to where segment goes
|
getlvalue_msw(cs); // point to where segment goes
|
||||||
cs.Iop = 0x8C;
|
cs.Iop = 0x8C;
|
||||||
NEWREG(cs.Irm,0);
|
NEWREG(cs.Irm,0);
|
||||||
cdb.gen(&cs); // MOV EA+2,ES
|
cdb.gen(&cs); // MOV EA+2,ES
|
||||||
|
@ -755,7 +755,7 @@ void cdeq(ref CGstate cg, ref CodeBuilder cdb,elem *e,regm_t *pretregs)
|
||||||
cdb.gen(&cs); // MOV EA+offset,reg
|
cdb.gen(&cs); // MOV EA+offset,reg
|
||||||
if (sz <= REGSIZE)
|
if (sz <= REGSIZE)
|
||||||
break;
|
break;
|
||||||
getlvalue_msw(&cs);
|
getlvalue_msw(cs);
|
||||||
reg = findregmsw(retregs);
|
reg = findregmsw(retregs);
|
||||||
code_newreg(&cs, reg);
|
code_newreg(&cs, reg);
|
||||||
}
|
}
|
||||||
|
@ -927,7 +927,7 @@ void cdaddass(ref CGstate cg, ref CodeBuilder cdb,elem *e,regm_t *pretregs)
|
||||||
|
|
||||||
if (op == OPnegass)
|
if (op == OPnegass)
|
||||||
{
|
{
|
||||||
getlvalue(cdb,&cs,e1,0);
|
getlvalue(cdb,cs,e1,0);
|
||||||
modEA(cdb,&cs);
|
modEA(cdb,&cs);
|
||||||
cs.Irm |= modregrm(0,3,0);
|
cs.Irm |= modregrm(0,3,0);
|
||||||
cs.Iop = op1;
|
cs.Iop = op1;
|
||||||
|
@ -950,13 +950,13 @@ void cdaddass(ref CGstate cg, ref CodeBuilder cdb,elem *e,regm_t *pretregs)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
neg_2reg:
|
neg_2reg:
|
||||||
getlvalue_msw(&cs);
|
getlvalue_msw(cs);
|
||||||
cdb.gen(&cs); // NEG EA+2
|
cdb.gen(&cs); // NEG EA+2
|
||||||
getlvalue_lsw(&cs);
|
getlvalue_lsw(cs);
|
||||||
cdb.gen(&cs); // NEG EA
|
cdb.gen(&cs); // NEG EA
|
||||||
code_orflag(cdb.last(),CFpsw);
|
code_orflag(cdb.last(),CFpsw);
|
||||||
cs.Iop = 0x81;
|
cs.Iop = 0x81;
|
||||||
getlvalue_msw(&cs);
|
getlvalue_msw(cs);
|
||||||
cs.IFL2 = FLconst;
|
cs.IFL2 = FLconst;
|
||||||
cs.IEV2.Vuns = 0;
|
cs.IEV2.Vuns = 0;
|
||||||
cdb.gen(&cs); // SBB EA+2,0
|
cdb.gen(&cs); // SBB EA+2,0
|
||||||
|
@ -989,7 +989,7 @@ void cdaddass(ref CGstate cg, ref CodeBuilder cdb,elem *e,regm_t *pretregs)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
getlvalue(cdb,&cs,e1,0);
|
getlvalue(cdb,cs,e1,0);
|
||||||
modEA(cdb,&cs);
|
modEA(cdb,&cs);
|
||||||
cs.IFL2 = FLconst;
|
cs.IFL2 = FLconst;
|
||||||
cs.IEV2.Vsize_t = e2.Vint;
|
cs.IEV2.Vsize_t = e2.Vint;
|
||||||
|
@ -1136,7 +1136,7 @@ void cdaddass(ref CGstate cg, ref CodeBuilder cdb,elem *e,regm_t *pretregs)
|
||||||
cdb.gen(&cs);
|
cdb.gen(&cs);
|
||||||
cs.Iflags &= ~CFpsw;
|
cs.Iflags &= ~CFpsw;
|
||||||
|
|
||||||
getlvalue_msw(&cs); // point to msw
|
getlvalue_msw(cs); // point to msw
|
||||||
msw = cast(uint)MSREG(e.E2.Vllong);
|
msw = cast(uint)MSREG(e.E2.Vllong);
|
||||||
cs.IEV2.Vuns = msw; // msw of constant
|
cs.IEV2.Vuns = msw; // msw of constant
|
||||||
switch (op)
|
switch (op)
|
||||||
|
@ -1163,7 +1163,7 @@ void cdaddass(ref CGstate cg, ref CodeBuilder cdb,elem *e,regm_t *pretregs)
|
||||||
!evalinregister(e2) &&
|
!evalinregister(e2) &&
|
||||||
sz <= REGSIZE) // deal with later
|
sz <= REGSIZE) // deal with later
|
||||||
{
|
{
|
||||||
getlvalue(cdb,&cs,e2,0);
|
getlvalue(cdb,cs,e2,0);
|
||||||
freenode(e2);
|
freenode(e2);
|
||||||
getregs(cdb,varregm);
|
getregs(cdb,varregm);
|
||||||
code_newreg(&cs, varreg);
|
code_newreg(&cs, varreg);
|
||||||
|
@ -1188,7 +1188,7 @@ void cdaddass(ref CGstate cg, ref CodeBuilder cdb,elem *e,regm_t *pretregs)
|
||||||
* e1 += (x >= y) SBB EA,-1
|
* e1 += (x >= y) SBB EA,-1
|
||||||
* e1 -= (x >= y) ADC EA,-1
|
* e1 -= (x >= y) ADC EA,-1
|
||||||
*/
|
*/
|
||||||
getlvalue(cdb,&cs,e1,0); // get lvalue
|
getlvalue(cdb,cs,e1,0); // get lvalue
|
||||||
modEA(cdb,&cs);
|
modEA(cdb,&cs);
|
||||||
regm_t keepmsk = idxregm(&cs);
|
regm_t keepmsk = idxregm(&cs);
|
||||||
retregs = mPSW;
|
retregs = mPSW;
|
||||||
|
@ -1218,7 +1218,7 @@ void cdaddass(ref CGstate cg, ref CodeBuilder cdb,elem *e,regm_t *pretregs)
|
||||||
if (tyml == TYhptr)
|
if (tyml == TYhptr)
|
||||||
retregs &= ~mCX; // need CX for shift count
|
retregs &= ~mCX; // need CX for shift count
|
||||||
scodelem(cgstate,cdb,e.E2,&retregs,0,true); // get rvalue
|
scodelem(cgstate,cdb,e.E2,&retregs,0,true); // get rvalue
|
||||||
getlvalue(cdb,&cs,e1,retregs); // get lvalue
|
getlvalue(cdb,cs,e1,retregs); // get lvalue
|
||||||
modEA(cdb,&cs);
|
modEA(cdb,&cs);
|
||||||
cs.Iop = op1;
|
cs.Iop = op1;
|
||||||
if (sz <= REGSIZE || tyfv(tyml))
|
if (sz <= REGSIZE || tyfv(tyml))
|
||||||
|
@ -1252,7 +1252,7 @@ void cdaddass(ref CGstate cg, ref CodeBuilder cdb,elem *e,regm_t *pretregs)
|
||||||
genshift(cdb); // MOV CX,offset __AHSHIFT
|
genshift(cdb); // MOV CX,offset __AHSHIFT
|
||||||
cdb.gen2(0xD3,modregrm(3,4,mreg)); // SHL mreg,CL
|
cdb.gen2(0xD3,modregrm(3,4,mreg)); // SHL mreg,CL
|
||||||
NEWREG(cs.Irm,mreg); // ADD EA+2,mreg
|
NEWREG(cs.Irm,mreg); // ADD EA+2,mreg
|
||||||
getlvalue_msw(&cs);
|
getlvalue_msw(cs);
|
||||||
}
|
}
|
||||||
else if (sz == 2 * REGSIZE)
|
else if (sz == 2 * REGSIZE)
|
||||||
{
|
{
|
||||||
|
@ -1261,7 +1261,7 @@ void cdaddass(ref CGstate cg, ref CodeBuilder cdb,elem *e,regm_t *pretregs)
|
||||||
code_orflag(cdb.last(),cflags);
|
code_orflag(cdb.last(),cflags);
|
||||||
cs.Iop = op2;
|
cs.Iop = op2;
|
||||||
NEWREG(cs.Irm,findregmsw(retregs)); // OP2 EA+1,reg
|
NEWREG(cs.Irm,findregmsw(retregs)); // OP2 EA+1,reg
|
||||||
getlvalue_msw(&cs);
|
getlvalue_msw(cs);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
assert(0);
|
assert(0);
|
||||||
|
@ -1318,7 +1318,7 @@ void cdaddass(ref CGstate cg, ref CodeBuilder cdb,elem *e,regm_t *pretregs)
|
||||||
regm_t idxregs;
|
regm_t idxregs;
|
||||||
|
|
||||||
if (tyml == TYhptr)
|
if (tyml == TYhptr)
|
||||||
getlvalue_lsw(&cs);
|
getlvalue_lsw(cs);
|
||||||
idxregs = idxregm(&cs);
|
idxregs = idxregm(&cs);
|
||||||
retregs = forregs & ~idxregs;
|
retregs = forregs & ~idxregs;
|
||||||
if (!(retregs & IDXREGS))
|
if (!(retregs & IDXREGS))
|
||||||
|
@ -1336,7 +1336,7 @@ void cdaddass(ref CGstate cg, ref CodeBuilder cdb,elem *e,regm_t *pretregs)
|
||||||
{
|
{
|
||||||
cs.Iop = LOD;
|
cs.Iop = LOD;
|
||||||
cdb.gen(&cs); // MOV lreg,EA
|
cdb.gen(&cs); // MOV lreg,EA
|
||||||
getlvalue_msw(&cs);
|
getlvalue_msw(cs);
|
||||||
if (I32)
|
if (I32)
|
||||||
cs.Iflags |= CFopsize;
|
cs.Iflags |= CFopsize;
|
||||||
NEWREG(cs.Irm,reg);
|
NEWREG(cs.Irm,reg);
|
||||||
|
@ -1355,7 +1355,7 @@ void cdaddass(ref CGstate cg, ref CodeBuilder cdb,elem *e,regm_t *pretregs)
|
||||||
|
|
||||||
code csl = cs;
|
code csl = cs;
|
||||||
NEWREG(csl.Irm,findreglsw(retregs));
|
NEWREG(csl.Irm,findreglsw(retregs));
|
||||||
getlvalue_lsw(&csl);
|
getlvalue_lsw(csl);
|
||||||
|
|
||||||
if (mask(reg) & idx)
|
if (mask(reg) & idx)
|
||||||
{
|
{
|
||||||
|
@ -1458,7 +1458,7 @@ void cdmulass(ref CGstate cg, ref CodeBuilder cdb,elem *e,regm_t *pretregs)
|
||||||
case 9: ss = 3; goto L4;
|
case 9: ss = 3; goto L4;
|
||||||
L4:
|
L4:
|
||||||
{
|
{
|
||||||
getlvalue(cdb,&cs,e1,0); // get EA
|
getlvalue(cdb,cs,e1,0); // get EA
|
||||||
modEA(cdb,&cs);
|
modEA(cdb,&cs);
|
||||||
freenode(e2);
|
freenode(e2);
|
||||||
regm_t idxregs = idxregm(&cs);
|
regm_t idxregs = idxregm(&cs);
|
||||||
|
@ -1498,7 +1498,7 @@ void cdmulass(ref CGstate cg, ref CodeBuilder cdb,elem *e,regm_t *pretregs)
|
||||||
goto L5;
|
goto L5;
|
||||||
L5:
|
L5:
|
||||||
{
|
{
|
||||||
getlvalue(cdb,&cs,e1,0); // get EA
|
getlvalue(cdb,cs,e1,0); // get EA
|
||||||
modEA(cdb,&cs);
|
modEA(cdb,&cs);
|
||||||
freenode(e2);
|
freenode(e2);
|
||||||
regm_t idxregs = idxregm(&cs);
|
regm_t idxregs = idxregm(&cs);
|
||||||
|
@ -1544,7 +1544,7 @@ void cdmulass(ref CGstate cg, ref CodeBuilder cdb,elem *e,regm_t *pretregs)
|
||||||
if (I64 && sz == 8 && e2factor != cast(int)e2factor)
|
if (I64 && sz == 8 && e2factor != cast(int)e2factor)
|
||||||
goto L1;
|
goto L1;
|
||||||
freenode(e2);
|
freenode(e2);
|
||||||
getlvalue(cdb,&cs,e1,0); // get EA
|
getlvalue(cdb,cs,e1,0); // get EA
|
||||||
regm_t idxregs = idxregm(&cs);
|
regm_t idxregs = idxregm(&cs);
|
||||||
retregs = *pretregs & (ALLREGS | mBP) & ~idxregs;
|
retregs = *pretregs & (ALLREGS | mBP) & ~idxregs;
|
||||||
if (!retregs)
|
if (!retregs)
|
||||||
|
@ -1562,7 +1562,7 @@ void cdmulass(ref CGstate cg, ref CodeBuilder cdb,elem *e,regm_t *pretregs)
|
||||||
if (!retregs)
|
if (!retregs)
|
||||||
retregs = ALLREGS;
|
retregs = ALLREGS;
|
||||||
codelem(cgstate,cdb,e2,&retregs,false); // load rvalue in reg
|
codelem(cgstate,cdb,e2,&retregs,false); // load rvalue in reg
|
||||||
getlvalue(cdb,&cs,e1,retregs); // get EA
|
getlvalue(cdb,cs,e1,retregs); // get EA
|
||||||
getregs(cdb,retregs); // destroy these regs
|
getregs(cdb,retregs); // destroy these regs
|
||||||
cs.Iop = 0x0FAF; // IMUL resreg,EA
|
cs.Iop = 0x0FAF; // IMUL resreg,EA
|
||||||
resreg = findreg(retregs);
|
resreg = findreg(retregs);
|
||||||
|
@ -1572,7 +1572,7 @@ void cdmulass(ref CGstate cg, ref CodeBuilder cdb,elem *e,regm_t *pretregs)
|
||||||
{
|
{
|
||||||
retregs = mAX;
|
retregs = mAX;
|
||||||
codelem(cgstate,cdb,e2,&retregs,false); // load rvalue in AX
|
codelem(cgstate,cdb,e2,&retregs,false); // load rvalue in AX
|
||||||
getlvalue(cdb,&cs,e1,mAX); // get EA
|
getlvalue(cdb,cs,e1,mAX); // get EA
|
||||||
getregs(cdb,isbyte ? mAX : mAX | mDX); // destroy these regs
|
getregs(cdb,isbyte ? mAX : mAX | mDX); // destroy these regs
|
||||||
cs.Iop = 0xF7 ^ isbyte; // [I]MUL EA
|
cs.Iop = 0xF7 ^ isbyte; // [I]MUL EA
|
||||||
opr = uns ? 4 : 5; // MUL/IMUL
|
opr = uns ? 4 : 5; // MUL/IMUL
|
||||||
|
@ -1629,14 +1629,14 @@ void cdmulass(ref CGstate cg, ref CodeBuilder cdb,elem *e,regm_t *pretregs)
|
||||||
retregs = mDX | mAX;
|
retregs = mDX | mAX;
|
||||||
regm_t rretregs = (config.target_cpu >= TARGET_PentiumPro) ? cgstate.allregs & ~retregs : mCX | mBX;
|
regm_t rretregs = (config.target_cpu >= TARGET_PentiumPro) ? cgstate.allregs & ~retregs : mCX | mBX;
|
||||||
codelem(cgstate,cdb,e2,&rretregs,false);
|
codelem(cgstate,cdb,e2,&rretregs,false);
|
||||||
getlvalue(cdb,&cs,e1,retregs | rretregs);
|
getlvalue(cdb,cs,e1,retregs | rretregs);
|
||||||
getregs(cdb,retregs);
|
getregs(cdb,retregs);
|
||||||
cs.Iop = LOD;
|
cs.Iop = LOD;
|
||||||
cdb.gen(&cs); // MOV AX,EA
|
cdb.gen(&cs); // MOV AX,EA
|
||||||
getlvalue_msw(&cs);
|
getlvalue_msw(cs);
|
||||||
cs.Irm |= modregrm(0,DX,0);
|
cs.Irm |= modregrm(0,DX,0);
|
||||||
cdb.gen(&cs); // MOV DX,EA+2
|
cdb.gen(&cs); // MOV DX,EA+2
|
||||||
getlvalue_lsw(&cs);
|
getlvalue_lsw(cs);
|
||||||
if (config.target_cpu >= TARGET_PentiumPro)
|
if (config.target_cpu >= TARGET_PentiumPro)
|
||||||
{
|
{
|
||||||
regm_t rlo = findreglsw(rretregs);
|
regm_t rlo = findreglsw(rretregs);
|
||||||
|
@ -1766,7 +1766,7 @@ void cddivass(ref CGstate cg, ref CodeBuilder cdb,elem *e,regm_t *pretregs)
|
||||||
|
|
||||||
freenode(e2);
|
freenode(e2);
|
||||||
|
|
||||||
getlvalue(cdb,&cs,e1,mAX | mDX);
|
getlvalue(cdb,cs,e1,mAX | mDX);
|
||||||
const reg = opAssLoadReg(cdb, cs, e, cgstate.allregs & ~( mAX | mDX | idxregm(&cs))); // MOV reg,EA
|
const reg = opAssLoadReg(cdb, cs, e, cgstate.allregs & ~( mAX | mDX | idxregm(&cs))); // MOV reg,EA
|
||||||
getregs(cdb, mAX|mDX);
|
getregs(cdb, mAX|mDX);
|
||||||
|
|
||||||
|
@ -1859,7 +1859,7 @@ void cddivass(ref CGstate cg, ref CodeBuilder cdb,elem *e,regm_t *pretregs)
|
||||||
assert(shpre == 0);
|
assert(shpre == 0);
|
||||||
|
|
||||||
freenode(e2);
|
freenode(e2);
|
||||||
getlvalue(cdb,&cs,e1,mAX | mDX);
|
getlvalue(cdb,cs,e1,mAX | mDX);
|
||||||
regm_t idxregs = idxregm(&cs);
|
regm_t idxregs = idxregm(&cs);
|
||||||
reg = opAssLoadReg(cdb, cs, e, cgstate.allregs & ~(mAX|mDX | idxregs)); // MOV reg,EA
|
reg = opAssLoadReg(cdb, cs, e, cgstate.allregs & ~(mAX|mDX | idxregs)); // MOV reg,EA
|
||||||
getregs(cdb, mAX|mDX);
|
getregs(cdb, mAX|mDX);
|
||||||
|
@ -1893,7 +1893,7 @@ void cddivass(ref CGstate cg, ref CodeBuilder cdb,elem *e,regm_t *pretregs)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
freenode(e2);
|
freenode(e2);
|
||||||
getlvalue(cdb,&cs,e1,mAX | mDX);
|
getlvalue(cdb,cs,e1,mAX | mDX);
|
||||||
regm_t idxregs = idxregm(&cs);
|
regm_t idxregs = idxregm(&cs);
|
||||||
reg = opAssLoadReg(cdb, cs, e, cgstate.allregs & ~(mAX|mDX | idxregs)); // MOV reg,EA
|
reg = opAssLoadReg(cdb, cs, e, cgstate.allregs & ~(mAX|mDX | idxregs)); // MOV reg,EA
|
||||||
getregs(cdb, mAX|mDX);
|
getregs(cdb, mAX|mDX);
|
||||||
|
@ -1978,7 +1978,7 @@ void cddivass(ref CGstate cg, ref CodeBuilder cdb,elem *e,regm_t *pretregs)
|
||||||
/* This is better than the code further down because it is
|
/* This is better than the code further down because it is
|
||||||
* not constrained to using AX and DX.
|
* not constrained to using AX and DX.
|
||||||
*/
|
*/
|
||||||
getlvalue(cdb,&cs,e1,0);
|
getlvalue(cdb,cs,e1,0);
|
||||||
regm_t idxregs = idxregm(&cs);
|
regm_t idxregs = idxregm(&cs);
|
||||||
const reg = opAssLoadReg(cdb,cs,e,cgstate.allregs & ~idxregs); // MOV reg,EA
|
const reg = opAssLoadReg(cdb,cs,e,cgstate.allregs & ~idxregs); // MOV reg,EA
|
||||||
const r = allocScratchReg(cdb, cgstate.allregs & ~(idxregs | mask(reg)));
|
const r = allocScratchReg(cdb, cgstate.allregs & ~(idxregs | mask(reg)));
|
||||||
|
@ -1992,7 +1992,7 @@ void cddivass(ref CGstate cg, ref CodeBuilder cdb,elem *e,regm_t *pretregs)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Signed divide or modulo by power of 2
|
// Signed divide or modulo by power of 2
|
||||||
getlvalue(cdb,&cs,e1,mAX | mDX);
|
getlvalue(cdb,cs,e1,mAX | mDX);
|
||||||
opAssLoadReg(cdb,cs,e,mAX);
|
opAssLoadReg(cdb,cs,e,mAX);
|
||||||
|
|
||||||
getregs(cdb,mDX); // DX is scratch register
|
getregs(cdb,mDX); // DX is scratch register
|
||||||
|
@ -2043,7 +2043,7 @@ void cddivass(ref CGstate cg, ref CodeBuilder cdb,elem *e,regm_t *pretregs)
|
||||||
regm_t retregs = ALLREGS & ~(mAX|mDX); // DX gets sign extension
|
regm_t retregs = ALLREGS & ~(mAX|mDX); // DX gets sign extension
|
||||||
codelem(cgstate,cdb,e2,&retregs,false); // load rvalue in retregs
|
codelem(cgstate,cdb,e2,&retregs,false); // load rvalue in retregs
|
||||||
reg_t reg = findreg(retregs);
|
reg_t reg = findreg(retregs);
|
||||||
getlvalue(cdb,&cs,e1,mAX | mDX | retregs); // get EA
|
getlvalue(cdb,cs,e1,mAX | mDX | retregs); // get EA
|
||||||
getregs(cdb,mAX | mDX); // destroy these regs
|
getregs(cdb,mAX | mDX); // destroy these regs
|
||||||
cs.Irm |= modregrm(0,AX,0);
|
cs.Irm |= modregrm(0,AX,0);
|
||||||
cs.Iop = LOD;
|
cs.Iop = LOD;
|
||||||
|
@ -2325,7 +2325,7 @@ void cdshass(ref CGstate cg, ref CodeBuilder cdb,elem *e,regm_t *pretregs)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
freenode(e2);
|
freenode(e2);
|
||||||
getlvalue(cdb,&cs,e1,mCX); // get lvalue, preserve CX
|
getlvalue(cdb,cs,e1,mCX); // get lvalue, preserve CX
|
||||||
modEA(cdb,&cs); // check for modifying register
|
modEA(cdb,&cs); // check for modifying register
|
||||||
|
|
||||||
if (*pretregs == 0 || // if don't return result
|
if (*pretregs == 0 || // if don't return result
|
||||||
|
@ -2368,19 +2368,19 @@ void cdshass(ref CGstate cg, ref CodeBuilder cdb,elem *e,regm_t *pretregs)
|
||||||
cdb.gen(&cs); // cd: SHIFT EA
|
cdb.gen(&cs); // cd: SHIFT EA
|
||||||
cd = cdb.last();
|
cd = cdb.last();
|
||||||
code_orflag(cd,CFpsw);
|
code_orflag(cd,CFpsw);
|
||||||
getlvalue_msw(&cs);
|
getlvalue_msw(cs);
|
||||||
NEWREG(cs.Irm,op2);
|
NEWREG(cs.Irm,op2);
|
||||||
cdb.gen(&cs); // SHIFT EA
|
cdb.gen(&cs); // SHIFT EA
|
||||||
getlvalue_lsw(&cs);
|
getlvalue_lsw(cs);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
getlvalue_msw(&cs);
|
getlvalue_msw(cs);
|
||||||
cdb.gen(&cs);
|
cdb.gen(&cs);
|
||||||
cd = cdb.last();
|
cd = cdb.last();
|
||||||
code_orflag(cd,CFpsw);
|
code_orflag(cd,CFpsw);
|
||||||
NEWREG(cs.Irm,op2);
|
NEWREG(cs.Irm,op2);
|
||||||
getlvalue_lsw(&cs);
|
getlvalue_lsw(cs);
|
||||||
cdb.gen(&cs);
|
cdb.gen(&cs);
|
||||||
}
|
}
|
||||||
if (v == 0xD3) // if building a loop
|
if (v == 0xD3) // if building a loop
|
||||||
|
@ -2406,10 +2406,10 @@ void cdshass(ref CGstate cg, ref CodeBuilder cdb,elem *e,regm_t *pretregs)
|
||||||
|
|
||||||
// be careful not to trash any index regs
|
// be careful not to trash any index regs
|
||||||
// do MSW first (which can't be an index reg)
|
// do MSW first (which can't be an index reg)
|
||||||
getlvalue_msw(&cs);
|
getlvalue_msw(cs);
|
||||||
NEWREG(cs.Irm,reg);
|
NEWREG(cs.Irm,reg);
|
||||||
cdb.gen(&cs);
|
cdb.gen(&cs);
|
||||||
getlvalue_lsw(&cs);
|
getlvalue_lsw(cs);
|
||||||
reg = findreglsw(retregs);
|
reg = findreglsw(retregs);
|
||||||
NEWREG(cs.Irm,reg);
|
NEWREG(cs.Irm,reg);
|
||||||
cdb.gen(&cs);
|
cdb.gen(&cs);
|
||||||
|
@ -2425,7 +2425,7 @@ void cdshass(ref CGstate cg, ref CodeBuilder cdb,elem *e,regm_t *pretregs)
|
||||||
cdb.gen(&cs); // MOV reg,EA
|
cdb.gen(&cs); // MOV reg,EA
|
||||||
cs.Iop = 0x0B; // OR reg,EA+2
|
cs.Iop = 0x0B; // OR reg,EA+2
|
||||||
cs.Iflags |= CFpsw;
|
cs.Iflags |= CFpsw;
|
||||||
getlvalue_msw(&cs);
|
getlvalue_msw(cs);
|
||||||
cdb.gen(&cs);
|
cdb.gen(&cs);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2864,7 +2864,7 @@ void cdcmp(ref CGstate cg, ref CodeBuilder cdb,elem *e,regm_t *pretregs)
|
||||||
e1.Eoper == OPind) &&
|
e1.Eoper == OPind) &&
|
||||||
!evalinregister(e1))
|
!evalinregister(e1))
|
||||||
{
|
{
|
||||||
getlvalue(cdb,&cs,e1,RMload);
|
getlvalue(cdb,cs,e1,RMload);
|
||||||
freenode(e1);
|
freenode(e1);
|
||||||
if (evalinregister(e2))
|
if (evalinregister(e2))
|
||||||
{
|
{
|
||||||
|
@ -2880,7 +2880,7 @@ void cdcmp(ref CGstate cg, ref CodeBuilder cdb,elem *e,regm_t *pretregs)
|
||||||
{
|
{
|
||||||
rreg = findregmsw(rretregs);
|
rreg = findregmsw(rretregs);
|
||||||
cs.Irm |= modregrm(0,rreg,0);
|
cs.Irm |= modregrm(0,rreg,0);
|
||||||
getlvalue_msw(&cs);
|
getlvalue_msw(cs);
|
||||||
cdb.gen(&cs); // CMP EA+2,rreg
|
cdb.gen(&cs); // CMP EA+2,rreg
|
||||||
if (I32 && sz == 6)
|
if (I32 && sz == 6)
|
||||||
cdb.last().Iflags |= CFopsize; // seg is only 16 bits
|
cdb.last().Iflags |= CFopsize; // seg is only 16 bits
|
||||||
|
@ -2889,7 +2889,7 @@ void cdcmp(ref CGstate cg, ref CodeBuilder cdb,elem *e,regm_t *pretregs)
|
||||||
genjmp(cdb,JNE,FLcode,cast(block *) ce); // JNE nop
|
genjmp(cdb,JNE,FLcode,cast(block *) ce); // JNE nop
|
||||||
rreg = findreglsw(rretregs);
|
rreg = findreglsw(rretregs);
|
||||||
NEWREG(cs.Irm,rreg);
|
NEWREG(cs.Irm,rreg);
|
||||||
getlvalue_lsw(&cs);
|
getlvalue_lsw(cs);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -2910,7 +2910,7 @@ void cdcmp(ref CGstate cg, ref CodeBuilder cdb,elem *e,regm_t *pretregs)
|
||||||
{ cs.Iflags = (cs.Iflags & ~(CFoff | CFseg)) | CFseg;
|
{ cs.Iflags = (cs.Iflags & ~(CFoff | CFseg)) | CFseg;
|
||||||
cs.IEV2.Voffset = 0;
|
cs.IEV2.Voffset = 0;
|
||||||
}
|
}
|
||||||
getlvalue_msw(&cs);
|
getlvalue_msw(cs);
|
||||||
cdb.gen(&cs); // CMP EA+2,const
|
cdb.gen(&cs); // CMP EA+2,const
|
||||||
if (!I16 && sz == 6)
|
if (!I16 && sz == 6)
|
||||||
cdb.last().Iflags |= CFopsize; // seg is only 16 bits
|
cdb.last().Iflags |= CFopsize; // seg is only 16 bits
|
||||||
|
@ -2924,7 +2924,7 @@ void cdcmp(ref CGstate cg, ref CodeBuilder cdb,elem *e,regm_t *pretregs)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
assert(0);
|
assert(0);
|
||||||
getlvalue_lsw(&cs);
|
getlvalue_lsw(cs);
|
||||||
}
|
}
|
||||||
freenode(e2);
|
freenode(e2);
|
||||||
}
|
}
|
||||||
|
@ -3041,7 +3041,7 @@ void cdcmp(ref CGstate cg, ref CodeBuilder cdb,elem *e,regm_t *pretregs)
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
// CMP EA,e2
|
// CMP EA,e2
|
||||||
getlvalue(cdb,&cs,e1,RMload);
|
getlvalue(cdb,cs,e1,RMload);
|
||||||
freenode(e1);
|
freenode(e1);
|
||||||
cs.Iop = 0x39 ^ isbyte ^ reverse;
|
cs.Iop = 0x39 ^ isbyte ^ reverse;
|
||||||
code_newreg(&cs,reg);
|
code_newreg(&cs,reg);
|
||||||
|
@ -3072,7 +3072,7 @@ void cdcmp(ref CGstate cg, ref CodeBuilder cdb,elem *e,regm_t *pretregs)
|
||||||
if (e2.Eoper == OPind)
|
if (e2.Eoper == OPind)
|
||||||
{
|
{
|
||||||
NEWREG(cs.Irm,reg);
|
NEWREG(cs.Irm,reg);
|
||||||
getlvalue_lsw(&cs);
|
getlvalue_lsw(cs);
|
||||||
cdb.gen(&cs);
|
cdb.gen(&cs);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -3246,7 +3246,7 @@ void longcmp(ref CodeBuilder cdb,elem *e,bool jcond,uint fltarg,code *targ)
|
||||||
e1.Eoper == OPind) &&
|
e1.Eoper == OPind) &&
|
||||||
!evalinregister(e1))
|
!evalinregister(e1))
|
||||||
{
|
{
|
||||||
getlvalue(cdb,&cs,e1,0);
|
getlvalue(cdb,cs,e1,0);
|
||||||
freenode(e1);
|
freenode(e1);
|
||||||
if (evalinregister(e2))
|
if (evalinregister(e2))
|
||||||
{
|
{
|
||||||
|
@ -3259,7 +3259,7 @@ void longcmp(ref CodeBuilder cdb,elem *e,bool jcond,uint fltarg,code *targ)
|
||||||
rreg = findregmsw(rretregs);
|
rreg = findregmsw(rretregs);
|
||||||
cs.Iop = 0x39;
|
cs.Iop = 0x39;
|
||||||
cs.Irm |= modregrm(0,rreg,0);
|
cs.Irm |= modregrm(0,rreg,0);
|
||||||
getlvalue_msw(&cs);
|
getlvalue_msw(cs);
|
||||||
cdb.gen(&cs); // CMP EA+2,rreg
|
cdb.gen(&cs); // CMP EA+2,rreg
|
||||||
cdb.append(cdbjmp);
|
cdb.append(cdbjmp);
|
||||||
rreg = findreglsw(rretregs);
|
rreg = findreglsw(rretregs);
|
||||||
|
@ -3269,13 +3269,13 @@ void longcmp(ref CodeBuilder cdb,elem *e,bool jcond,uint fltarg,code *targ)
|
||||||
{
|
{
|
||||||
cse_flush(cdb,1);
|
cse_flush(cdb,1);
|
||||||
cs.Irm |= modregrm(0,7,0);
|
cs.Irm |= modregrm(0,7,0);
|
||||||
getlvalue_msw(&cs);
|
getlvalue_msw(cs);
|
||||||
cdb.gen(&cs); // CMP EA+2,const
|
cdb.gen(&cs); // CMP EA+2,const
|
||||||
cdb.append(cdbjmp);
|
cdb.append(cdbjmp);
|
||||||
cs.IEV2.Vint = e2.Vlong;
|
cs.IEV2.Vint = e2.Vlong;
|
||||||
freenode(e2);
|
freenode(e2);
|
||||||
}
|
}
|
||||||
getlvalue_lsw(&cs);
|
getlvalue_lsw(cs);
|
||||||
cdb.gen(&cs); // CMP EA,rreg/const
|
cdb.gen(&cs); // CMP EA,rreg/const
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -4200,7 +4200,7 @@ void cdbtst(ref CGstate cg, ref CodeBuilder cdb, elem *e, regm_t *pretregs)
|
||||||
regm_t idxregs;
|
regm_t idxregs;
|
||||||
if ((e1.Eoper == OPind && !e1.Ecount) || e1.Eoper == OPvar)
|
if ((e1.Eoper == OPind && !e1.Ecount) || e1.Eoper == OPvar)
|
||||||
{
|
{
|
||||||
getlvalue(cdb, &cs, e1, RMload); // get addressing mode
|
getlvalue(cdb, cs, e1, RMload); // get addressing mode
|
||||||
idxregs = idxregm(&cs); // mask if index regs used
|
idxregs = idxregm(&cs); // mask if index regs used
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -4337,7 +4337,7 @@ void cdbt(ref CGstate cg, ref CodeBuilder cdb,elem *e, regm_t *pretregs)
|
||||||
code cs;
|
code cs;
|
||||||
cs.Iflags = 0;
|
cs.Iflags = 0;
|
||||||
|
|
||||||
getlvalue(cdb, &cs, e, RMload); // get addressing mode
|
getlvalue(cdb, cs, e, RMload); // get addressing mode
|
||||||
if (e.Eoper == OPbt && *pretregs == 0)
|
if (e.Eoper == OPbt && *pretregs == 0)
|
||||||
{
|
{
|
||||||
codelem(cgstate,cdb,e2,pretregs,false);
|
codelem(cgstate,cdb,e2,pretregs,false);
|
||||||
|
@ -4449,7 +4449,7 @@ void cdbscan(ref CGstate cg, ref CodeBuilder cdb, elem *e, regm_t *pretregs)
|
||||||
|
|
||||||
if ((e.E1.Eoper == OPind && !e.E1.Ecount) || e.E1.Eoper == OPvar)
|
if ((e.E1.Eoper == OPind && !e.E1.Ecount) || e.E1.Eoper == OPvar)
|
||||||
{
|
{
|
||||||
getlvalue(cdb, &cs, e.E1, RMload); // get addressing mode
|
getlvalue(cdb, cs, e.E1, RMload); // get addressing mode
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -4503,7 +4503,7 @@ void cdpopcnt(ref CGstate cg, ref CodeBuilder cdb,elem *e,regm_t *pretregs)
|
||||||
code cs = void;
|
code cs = void;
|
||||||
if ((e.E1.Eoper == OPind && !e.E1.Ecount) || e.E1.Eoper == OPvar)
|
if ((e.E1.Eoper == OPind && !e.E1.Ecount) || e.E1.Eoper == OPvar)
|
||||||
{
|
{
|
||||||
getlvalue(cdb, &cs, e.E1, RMload); // get addressing mode
|
getlvalue(cdb, cs, e.E1, RMload); // get addressing mode
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -4641,7 +4641,7 @@ void cdcmpxchg(ref CGstate cg, ref CodeBuilder cdb, elem *e, regm_t *pretregs)
|
||||||
scodelem(cgstate,cdb,e2.E2,&retregs,mDX|mAX,false); // [CX,BX] = e2.E2
|
scodelem(cgstate,cdb,e2.E2,&retregs,mDX|mAX,false); // [CX,BX] = e2.E2
|
||||||
|
|
||||||
code cs = void;
|
code cs = void;
|
||||||
getlvalue(cdb,&cs,e1,mCX|mBX|mAX|mDX); // get EA
|
getlvalue(cdb,cs,e1,mCX|mBX|mAX|mDX); // get EA
|
||||||
|
|
||||||
getregs(cdb,mDX|mAX); // CMPXCHG destroys these regs
|
getregs(cdb,mDX|mAX); // CMPXCHG destroys these regs
|
||||||
|
|
||||||
|
@ -4668,7 +4668,7 @@ void cdcmpxchg(ref CGstate cg, ref CodeBuilder cdb, elem *e, regm_t *pretregs)
|
||||||
scodelem(cgstate,cdb,e2.E2,&retregs,mAX,false); // load rvalue in reg
|
scodelem(cgstate,cdb,e2.E2,&retregs,mAX,false); // load rvalue in reg
|
||||||
|
|
||||||
code cs = void;
|
code cs = void;
|
||||||
getlvalue(cdb,&cs,e1,mAX | retregs); // get EA
|
getlvalue(cdb,cs,e1,mAX | retregs); // get EA
|
||||||
|
|
||||||
getregs(cdb,mAX); // CMPXCHG destroys AX
|
getregs(cdb,mAX); // CMPXCHG destroys AX
|
||||||
|
|
||||||
|
@ -4734,7 +4734,7 @@ void cdprefetch(ref CGstate cg, ref CodeBuilder cdb, elem *e, regm_t *pretregs)
|
||||||
freenode(e.E2);
|
freenode(e.E2);
|
||||||
|
|
||||||
code cs = void;
|
code cs = void;
|
||||||
getlvalue(cdb,&cs,e1,0);
|
getlvalue(cdb,cs,e1,0);
|
||||||
cs.Iop = op;
|
cs.Iop = op;
|
||||||
cs.Irm |= modregrm(0,reg,0);
|
cs.Irm |= modregrm(0,reg,0);
|
||||||
cs.Iflags |= CFvolatile; // do not schedule
|
cs.Iflags |= CFvolatile; // do not schedule
|
||||||
|
@ -4780,7 +4780,7 @@ reg_t opAssLoadReg(ref CodeBuilder cdb, ref code cs, elem* e, regm_t retregs)
|
||||||
private
|
private
|
||||||
void opAssLoadPair(ref CodeBuilder cdb, ref code cs, elem* e, out reg_t rhi, out reg_t rlo, regm_t retregs, regm_t keepmsk)
|
void opAssLoadPair(ref CodeBuilder cdb, ref code cs, elem* e, out reg_t rhi, out reg_t rlo, regm_t retregs, regm_t keepmsk)
|
||||||
{
|
{
|
||||||
getlvalue(cdb,&cs,e.E1,retregs | keepmsk);
|
getlvalue(cdb,cs,e.E1,retregs | keepmsk);
|
||||||
const tym_t tyml = tybasic(e.E1.Ety); // type of lvalue
|
const tym_t tyml = tybasic(e.E1.Ety); // type of lvalue
|
||||||
allocreg(cdb,retregs,tyml);
|
allocreg(cdb,retregs,tyml);
|
||||||
|
|
||||||
|
@ -4790,10 +4790,10 @@ void opAssLoadPair(ref CodeBuilder cdb, ref code cs, elem* e, out reg_t rhi, out
|
||||||
cs.Iop = LOD;
|
cs.Iop = LOD;
|
||||||
code_newreg(&cs,rlo);
|
code_newreg(&cs,rlo);
|
||||||
cdb.gen(&cs); // MOV rlo,EA
|
cdb.gen(&cs); // MOV rlo,EA
|
||||||
getlvalue_msw(&cs);
|
getlvalue_msw(cs);
|
||||||
code_newreg(&cs,rhi);
|
code_newreg(&cs,rhi);
|
||||||
cdb.gen(&cs); // MOV rhi,EA+2
|
cdb.gen(&cs); // MOV rhi,EA+2
|
||||||
getlvalue_lsw(&cs);
|
getlvalue_lsw(cs);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -4841,7 +4841,7 @@ void opAssStorePair(ref CodeBuilder cdb, ref code cs, elem* e, reg_t rhi, reg_t
|
||||||
code_newreg(&cs,rlo);
|
code_newreg(&cs,rlo);
|
||||||
cdb.gen(&cs); // MOV EA,lsreg
|
cdb.gen(&cs); // MOV EA,lsreg
|
||||||
code_newreg(&cs,rhi);
|
code_newreg(&cs,rhi);
|
||||||
getlvalue_msw(&cs);
|
getlvalue_msw(cs);
|
||||||
cdb.gen(&cs); // MOV EA+REGSIZE,msreg
|
cdb.gen(&cs); // MOV EA+REGSIZE,msreg
|
||||||
const regm_t retregs = mask(rhi) | mask(rlo);
|
const regm_t retregs = mask(rhi) | mask(rlo);
|
||||||
elem* e1 = e.E1;
|
elem* e1 = e.E1;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue