update getlvalue() with ref parameter

This commit is contained in:
Walter Bright 2024-06-17 22:47:56 -07:00 committed by The Dlang Bot
parent 1cdf7e2505
commit 179e8d68eb
6 changed files with 138 additions and 138 deletions

View file

@ -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)

View file

@ -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;

View file

@ -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);

View file

@ -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 */

View file

@ -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

View file

@ -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;