Skip to content

Commit

Permalink
Merge pull request #9324 from WalterBright/cgxmm_opcode
Browse files Browse the repository at this point in the history
cgxmm.d: add opcode_t
  • Loading branch information
WalterBright authored Feb 5, 2019
2 parents 4553470 + b4588fa commit 8adbfee
Show file tree
Hide file tree
Showing 4 changed files with 40 additions and 35 deletions.
69 changes: 36 additions & 33 deletions src/dmd/backend/cgxmm.d
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ uint mask(uint m);
* Is operator a store operator?
*/

bool isXMMstore(uint op)
bool isXMMstore(opcode_t op)
{
switch (op)
{
Expand Down Expand Up @@ -89,7 +89,7 @@ private void movxmmconst(ref CodeBuilder cdb, uint xreg, uint sz, targ_size_t va
movregconst(cdb,r,p[1],0);
cdb.genfltreg(STO,r,4); // MOV floatreg+4,r

uint op = xmmload(TYdouble, true);
const op = xmmload(TYdouble, true);
cdb.genxmmreg(op,xreg,0,TYdouble); // MOVSD XMMreg,floatreg
}
else
Expand Down Expand Up @@ -147,16 +147,16 @@ void orthxmm(ref CodeBuilder cdb, elem *e, regm_t *pretregs)
retregs |= rretregs;
if (e.Eoper == OPmin)
{
uint nretregs = XMMREGS & ~retregs;
regm_t nretregs = XMMREGS & ~retregs;
reg_t sreg; // hold sign bit
uint sz = tysize(e1.Ety);
const uint sz = tysize(e1.Ety);
allocreg(cdb,&nretregs,&sreg,e2.Ety);
targ_size_t signbit = 0x80000000;
if (sz == 8)
signbit = cast(targ_size_t)0x8000000000000000L;
movxmmconst(cdb,sreg, sz, signbit, 0);
getregs(cdb,nretregs);
uint xop = (sz == 8) ? XORPD : XORPS; // XORPD/S rreg,sreg
const opcode_t xop = (sz == 8) ? XORPD : XORPS; // XORPD/S rreg,sreg
cdb.gen2(xop,modregxrmx(3,rreg-XMM0,sreg-XMM0));
}
if (retregs != *pretregs)
Expand Down Expand Up @@ -195,9 +195,11 @@ void orthxmm(ref CodeBuilder cdb, elem *e, regm_t *pretregs)

/************************
* Generate code for an assignment using XMM registers.
* Params:
* opcode = store opcode to use, CMP means generate one
*/

void xmmeq(ref CodeBuilder cdb, elem *e, uint op, elem *e1, elem *e2,regm_t *pretregs)
void xmmeq(ref CodeBuilder cdb, elem *e, opcode_t op, elem *e1, elem *e2,regm_t *pretregs)
{
tym_t tymll;
int i;
Expand All @@ -208,15 +210,15 @@ void xmmeq(ref CodeBuilder cdb, elem *e, uint op, elem *e1, elem *e2,regm_t *pre
targ_int postinc;

//printf("xmmeq(e1 = %p, e2 = %p, *pretregs = %s)\n", e1, e2, regm_str(*pretregs));
int e2oper = e2.Eoper;
tym_t tyml = tybasic(e1.Ety); /* type of lvalue */
regm_t retregs = *pretregs;

if (!(retregs & XMMREGS))
retregs = XMMREGS; // pick any XMM reg

bool aligned = xmmIsAligned(e1);
cs.Iop = (op == OPeq) ? xmmstore(tyml, aligned) : op;
// If default, select store opcode
cs.Iop = (op == CMP) ? xmmstore(tyml, aligned) : op;
regvar = false;
varregm = 0;
if (config.flags4 & CFG4optimized)
Expand Down Expand Up @@ -285,7 +287,7 @@ void xmmeq(ref CodeBuilder cdb, elem *e, uint op, elem *e1, elem *e2,regm_t *pre
Lp:
if (postinc)
{
uint increg = findreg(idxregm(&cs)); // the register to increment
const increg = findreg(idxregm(&cs)); // the register to increment
if (*pretregs & mPSW)
{ // Use LEA to avoid touching the flags
uint rm = cs.Irm & 7;
Expand Down Expand Up @@ -331,7 +333,8 @@ Lp:

void xmmcnvt(ref CodeBuilder cdb,elem *e,regm_t *pretregs)
{
uint op=0, regs;
opcode_t op = NoOpcode;
regm_t regs;
tym_t ty;
ubyte rex = 0;
bool zx = false; // zero extend uint
Expand Down Expand Up @@ -409,7 +412,7 @@ void xmmcnvt(ref CodeBuilder cdb,elem *e,regm_t *pretregs)
default:
assert(0);
}
assert(op);
assert(op != NoOpcode);

codelem(cdb,e1, &regs, false);
reg_t reg = findreg(regs);
Expand All @@ -423,7 +426,7 @@ void xmmcnvt(ref CodeBuilder cdb,elem *e,regm_t *pretregs)
code_orflag(cdb.last(),CFvolatile);
}

uint retregs = *pretregs;
regm_t retregs = *pretregs;
if (tyxmmreg(ty)) // target is XMM
{ if (!(*pretregs & XMMREGS))
retregs = XMMREGS;
Expand Down Expand Up @@ -579,9 +582,9 @@ void xmmpost(ref CodeBuilder cdb,elem *e,regm_t *pretregs)
if (!rretregs)
rretregs = XMMREGS & ~(retregs | resultregs);
codelem(cdb,e2,&rretregs,false); // eval right leaf
uint rreg = findreg(rretregs);
const rreg = findreg(rretregs);

uint op = xmmoperator(e1.Ety, e.Eoper);
const op = xmmoperator(e1.Ety, e.Eoper);
cdb.gen2(op,modregxrmx(3,reg-XMM0,rreg-XMM0)); // ADD reg,rreg
checkSetVex(cdb.last(), e1.Ety);

Expand Down Expand Up @@ -638,7 +641,7 @@ void xmmneg(ref CodeBuilder cdb,elem *e,regm_t *pretregs)
movxmmconst(cdb,rreg, sz, signbit, 0);

getregs(cdb,retregs);
uint op = (sz == 8) ? XORPD : XORPS; // XORPD/S reg,rreg
const op = (sz == 8) ? XORPD : XORPS; // XORPD/S reg,rreg
cdb.gen2(op,modregxrmx(3,reg-XMM0,rreg-XMM0));
fixresult(cdb,e,retregs,pretregs);
}
Expand All @@ -652,8 +655,9 @@ void xmmneg(ref CodeBuilder cdb,elem *e,regm_t *pretregs)
* aligned = for vectors, true if aligned to 16 bytes
*/

uint xmmload(tym_t tym, bool aligned)
{ uint op;
opcode_t xmmload(tym_t tym, bool aligned)
{
opcode_t op;
if (tysize(tym) == 32)
aligned = false;
switch (tybasic(tym))
Expand Down Expand Up @@ -703,8 +707,9 @@ uint xmmload(tym_t tym, bool aligned)
* Get correct store operator based on type.
*/

uint xmmstore(tym_t tym, bool aligned)
{ uint op;
opcode_t xmmstore(tym_t tym, bool aligned)
{
opcode_t op;
switch (tybasic(tym))
{
case TYuint:
Expand Down Expand Up @@ -753,10 +758,10 @@ uint xmmstore(tym_t tym, bool aligned)
* Get correct XMM operator based on type and operator.
*/

private uint xmmoperator(tym_t tym, uint oper)
private opcode_t xmmoperator(tym_t tym, OPER oper)
{
tym = tybasic(tym);
uint op;
opcode_t op;
switch (oper)
{
case OPadd:
Expand Down Expand Up @@ -1017,7 +1022,7 @@ void cdvector(ref CodeBuilder cdb, elem *e, regm_t *pretregs)
exit(1);
}

uint n = el_nparams(e.EV.E1);
const n = el_nparams(e.EV.E1);
elem **params = cast(elem **)malloc(n * (elem *).sizeof);
assert(params);
elem **tmp = params;
Expand All @@ -1036,7 +1041,7 @@ static if (0)
if (*pretregs == 0)
{ /* Evaluate for side effects only
*/
for (int i = 0; i < n; i++)
foreach (i; 0 .. n)
{
codelem(cdb,params[i], pretregs, false);
*pretregs = 0; // in case they got set
Expand All @@ -1055,11 +1060,9 @@ static if (0)
ty2 = tybasic(op2.Ety);
}

uint op = cast(uint)el_tolong(eop);
auto op = cast(opcode_t)el_tolong(eop);
debug assert(!isXMMstore(op));
tym_t ty1 = tybasic(op1.Ety);
uint sz1 = _tysize[ty1];
// assert(sz1 == 16); // float or double

regm_t retregs;
if (n == 3 && ty2 == TYuchar && op2.Eoper == OPconst)
Expand Down Expand Up @@ -1105,7 +1108,7 @@ static if (0)
{
regm_t rretregs = XMMREGS;
codelem(cdb,op1, &rretregs, false);
uint rreg = findreg(rretregs) - XMM0;
const rreg = findreg(rretregs) - XMM0;
cs.Irm = modregrm(3,0,rreg & 7);
cs.Iflags = 0;
cs.Irex = 0;
Expand Down Expand Up @@ -1143,9 +1146,9 @@ static if (0)
}
else
{
uint rretregs = XMMREGS & ~retregs;
regm_t rretregs = XMMREGS & ~retregs;
scodelem(cdb, op2, &rretregs, retregs, true);
uint rreg = findreg(rretregs) - XMM0;
const rreg = findreg(rretregs) - XMM0;
cs.Irm = modregrm(3,0,rreg & 7);
cs.Iflags = 0;
cs.Irex = 0;
Expand Down Expand Up @@ -1210,7 +1213,7 @@ void cdvecsto(ref CodeBuilder cdb, elem *e, regm_t *pretregs)
elem *op1 = e.EV.E1;
elem *op2 = e.EV.E2.EV.E2;
elem *eop = e.EV.E2.EV.E1;
uint op = cast(uint)el_tolong(eop);
const op = cast(opcode_t)el_tolong(eop);
debug assert(isXMMstore(op));
xmmeq(cdb, e, op, op1, op2, pretregs);
}
Expand Down Expand Up @@ -1242,7 +1245,7 @@ static if (0)
{
regm_t rretregs = XMMREGS & ~retregs;
cr = scodelem(op2, &rretregs, retregs, true);
uint rreg = findreg(rretregs) - XMM0;
const rreg = findreg(rretregs) - XMM0;
cs.Irm = modregrm(3,0,rreg & 7);
cs.Iflags = 0;
cs.Irex = 0;
Expand Down Expand Up @@ -1357,7 +1360,7 @@ static if (0)
{
regm_t regm = ALLREGS;
codelem(cdb,e1,&regm,false); // eval left leaf
uint r = findreg(regm);
const r = findreg(regm);

reg_t reg;
allocreg(cdb,&retregs,&reg, e.Ety);
Expand Down Expand Up @@ -1667,7 +1670,7 @@ void checkSetVex(code *c, tym_t ty)
break;
}

uint op = 0xC4000000 | (c.Iop & 0xFF);
opcode_t op = 0xC4000000 | (c.Iop & 0xFF);
switch (c.Iop & 0xFFFFFF00)
{
static uint MM_PP(uint mm, uint pp) { return (mm << 16) | (pp << 8); }
Expand Down
2 changes: 1 addition & 1 deletion src/dmd/backend/cod4.d
Original file line number Diff line number Diff line change
Expand Up @@ -362,7 +362,7 @@ void cdeq(ref CodeBuilder cdb,elem *e,regm_t *pretregs)

if (tyxmmreg(tyml) && config.fpxmmregs)
{
xmmeq(cdb, e, e.Eoper, e1, e2, pretregs);
xmmeq(cdb, e, CMP, e1, e2, pretregs);
return;
}

Expand Down
2 changes: 1 addition & 1 deletion src/dmd/backend/code.d
Original file line number Diff line number Diff line change
Expand Up @@ -595,7 +595,7 @@ void cod5_noprol();
/* cgxmm.c */
bool isXMMstore(uint op);
void orthxmm(ref CodeBuilder cdb, elem *e, regm_t *pretregs);
void xmmeq(ref CodeBuilder cdb, elem *e, uint op, elem *e1, elem *e2,regm_t *pretregs);
void xmmeq(ref CodeBuilder cdb, elem *e, opcode_t op, elem *e1, elem *e2, regm_t *pretregs);
void xmmcnvt(ref CodeBuilder cdb,elem *e,regm_t *pretregs);
void xmmopass(ref CodeBuilder cdb,elem *e, regm_t *pretregs);
void xmmpost(ref CodeBuilder cdb, elem *e, regm_t *pretregs);
Expand Down
2 changes: 2 additions & 0 deletions src/dmd/backend/code_x86.d
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import dmd.backend.el : elem;
import dmd.backend.ty : I64;

alias opcode_t = uint; // CPU opcode
enum opcode_t NoOpcode = 0xFFFF; // not a valid opcode_t

/* Register definitions */

Expand Down Expand Up @@ -413,6 +414,7 @@ enum
SEGFS = 0x64,
SEGGS = 0x65,

CMP = 0x3B,
CALL = 0xE8,
JMP = 0xE9, // Intra-Segment Direct
JMPS = 0xEB, // JMP SHORT
Expand Down

0 comments on commit 8adbfee

Please sign in to comment.