From b4588fa4e8b85f90d95cc239ab91b2cdd89b2ce8 Mon Sep 17 00:00:00 2001 From: Walter Bright Date: Mon, 4 Feb 2019 02:36:56 -0800 Subject: [PATCH] cgxmm.d: add opcode_t --- src/dmd/backend/cgxmm.d | 69 ++++++++++++++++++++------------------ src/dmd/backend/cod4.d | 2 +- src/dmd/backend/code.d | 2 +- src/dmd/backend/code_x86.d | 2 ++ 4 files changed, 40 insertions(+), 35 deletions(-) diff --git a/src/dmd/backend/cgxmm.d b/src/dmd/backend/cgxmm.d index be1eb8a0cdcd..56fa92880d0e 100644 --- a/src/dmd/backend/cgxmm.d +++ b/src/dmd/backend/cgxmm.d @@ -49,7 +49,7 @@ uint mask(uint m); * Is operator a store operator? */ -bool isXMMstore(uint op) +bool isXMMstore(opcode_t op) { switch (op) { @@ -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 @@ -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) @@ -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; @@ -208,7 +210,6 @@ 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; @@ -216,7 +217,8 @@ void xmmeq(ref CodeBuilder cdb, elem *e, uint op, elem *e1, elem *e2,regm_t *pre 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) @@ -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; @@ -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 @@ -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, ®s, false); reg_t reg = findreg(regs); @@ -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; @@ -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); @@ -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); } @@ -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)) @@ -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: @@ -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: @@ -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; @@ -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 @@ -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) @@ -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; @@ -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; @@ -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); } @@ -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; @@ -1357,7 +1360,7 @@ static if (0) { regm_t regm = ALLREGS; codelem(cdb,e1,®m,false); // eval left leaf - uint r = findreg(regm); + const r = findreg(regm); reg_t reg; allocreg(cdb,&retregs,®, e.Ety); @@ -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); } diff --git a/src/dmd/backend/cod4.d b/src/dmd/backend/cod4.d index 92a359929c89..3c82a9bcceb3 100644 --- a/src/dmd/backend/cod4.d +++ b/src/dmd/backend/cod4.d @@ -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; } diff --git a/src/dmd/backend/code.d b/src/dmd/backend/code.d index e6c519625164..d38adbf51680 100644 --- a/src/dmd/backend/code.d +++ b/src/dmd/backend/code.d @@ -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); diff --git a/src/dmd/backend/code_x86.d b/src/dmd/backend/code_x86.d index 7b0c7fff5d1f..b35d730906fe 100644 --- a/src/dmd/backend/code_x86.d +++ b/src/dmd/backend/code_x86.d @@ -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 */ @@ -413,6 +414,7 @@ enum SEGFS = 0x64, SEGGS = 0x65, + CMP = 0x3B, CALL = 0xE8, JMP = 0xE9, // Intra-Segment Direct JMPS = 0xEB, // JMP SHORT