mirror of
https://github.com/dlang/dmd.git
synced 2025-04-27 13:40:11 +03:00
add support for CMPPS and CMPPD instructions (#14593)
This commit is contained in:
parent
d747cd0006
commit
3e683fe6fe
3 changed files with 111 additions and 16 deletions
|
@ -247,6 +247,24 @@ void orthxmm(ref CodeBuilder cdb, elem *e, regm_t *pretregs)
|
||||||
|
|
||||||
getregs(cdb,retregs);
|
getregs(cdb,retregs);
|
||||||
cdb.gen2(op,modregxrmx(3,reg-XMM0,rreg-XMM0));
|
cdb.gen2(op,modregxrmx(3,reg-XMM0,rreg-XMM0));
|
||||||
|
if (op == CMPPS || op == CMPPD)
|
||||||
|
{
|
||||||
|
// https://www.felixcloutier.com/x86/cmpps
|
||||||
|
ubyte imm8;
|
||||||
|
switch (e.Eoper)
|
||||||
|
{
|
||||||
|
case OPeqeq: imm8 = 0; break;
|
||||||
|
case OPlt: imm8 = 1; break;
|
||||||
|
case OPle: imm8 = 2; break;
|
||||||
|
case OPne: imm8 = 4; break;
|
||||||
|
default:
|
||||||
|
elem_print(e);
|
||||||
|
assert(0); // not doing the unordered compares
|
||||||
|
}
|
||||||
|
code* c = cdb.last();
|
||||||
|
c.IFL2 = FLconst;
|
||||||
|
c.IEV2.Vsize_t = imm8;
|
||||||
|
}
|
||||||
checkSetVex(cdb.last(), e1.Ety);
|
checkSetVex(cdb.last(), e1.Ety);
|
||||||
if (retregs != *pretregs)
|
if (retregs != *pretregs)
|
||||||
fixresult(cdb,e,retregs,pretregs);
|
fixresult(cdb,e,retregs,pretregs);
|
||||||
|
@ -1121,6 +1139,13 @@ private opcode_t xmmoperator(tym_t tym, OPER oper)
|
||||||
case TYdouble:
|
case TYdouble:
|
||||||
case TYidouble: op = UCOMISD; break;
|
case TYidouble: op = UCOMISD; break;
|
||||||
|
|
||||||
|
case TYfloat4:
|
||||||
|
case TYfloat8:
|
||||||
|
case TYfloat16: op = CMPPS; break;
|
||||||
|
|
||||||
|
case TYdouble2:
|
||||||
|
case TYdouble4:
|
||||||
|
case TYdouble8: op = CMPPD; break;
|
||||||
default: assert(0);
|
default: assert(0);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -1821,24 +1821,14 @@ elem* toElem(Expression e, IRState *irs)
|
||||||
}
|
}
|
||||||
else if (t1.ty == Tvector)
|
else if (t1.ty == Tvector)
|
||||||
{
|
{
|
||||||
/* Rewrite in terms of < operator
|
|
||||||
*/
|
|
||||||
bool swap; // swap operands
|
|
||||||
bool comp; // complement result
|
|
||||||
switch (eop)
|
|
||||||
{
|
|
||||||
case OPgt: break; // x > y
|
|
||||||
case OPlt: swap = true; break; // y > x
|
|
||||||
case OPle: comp = true; break; // !(x > y)
|
|
||||||
case OPge: swap = true; comp = true; break; // !(y > x)
|
|
||||||
default: assert(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
elem* e1 = toElem(ce.e1, irs);
|
elem* e1 = toElem(ce.e1, irs);
|
||||||
elem* e2 = toElem(ce.e2, irs);
|
elem* e2 = toElem(ce.e2, irs);
|
||||||
|
|
||||||
elem* ex;
|
tym_t tym = totym(ce.type);
|
||||||
if (swap)
|
elem* ex; // store side effects in ex
|
||||||
|
|
||||||
|
// swap operands
|
||||||
|
void swapOps()
|
||||||
{
|
{
|
||||||
// put side effects of e1 into ex
|
// put side effects of e1 into ex
|
||||||
if (el_sideeffect(e1) && e2.Eoper != OPconst)
|
if (el_sideeffect(e1) && e2.Eoper != OPconst)
|
||||||
|
@ -1853,7 +1843,49 @@ elem* toElem(Expression e, IRState *irs)
|
||||||
e1 = tmp;
|
e1 = tmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
tym_t tym = totym(ce.type);
|
if (t1.isfloating())
|
||||||
|
{
|
||||||
|
/* Rewrite in terms of < or <= operator
|
||||||
|
*/
|
||||||
|
OPER op;
|
||||||
|
switch (eop)
|
||||||
|
{
|
||||||
|
case OPlt: // x < y
|
||||||
|
case OPle: // x <= y
|
||||||
|
op = eop;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case OPgt: op = OPlt; goto Lswap; // y < x
|
||||||
|
case OPge: op = OPle; goto Lswap; // y <= x
|
||||||
|
Lswap:
|
||||||
|
swapOps();
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
assert(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
e = el_bin(op, tym, e1, e2);
|
||||||
|
elem_setLoc(e, ce.loc);
|
||||||
|
e = el_combine(ex, e);
|
||||||
|
return e;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Rewrite in terms of > operator
|
||||||
|
*/
|
||||||
|
bool swap; // swap operands
|
||||||
|
bool comp; // complement result
|
||||||
|
switch (eop)
|
||||||
|
{
|
||||||
|
case OPgt: break; // x > y
|
||||||
|
case OPlt: swap = true; break; // y > x
|
||||||
|
case OPle: comp = true; break; // !(x > y)
|
||||||
|
case OPge: swap = true; comp = true; break; // !(y > x)
|
||||||
|
default: assert(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (swap)
|
||||||
|
swapOps();
|
||||||
|
|
||||||
if (t1.isunsigned() || t2.isunsigned())
|
if (t1.isunsigned() || t2.isunsigned())
|
||||||
{
|
{
|
||||||
|
|
|
@ -150,6 +150,42 @@ void testunscmp()
|
||||||
|
|
||||||
/*****************************************/
|
/*****************************************/
|
||||||
|
|
||||||
|
float4 testlt(float4 x, float4 y) { return x < y; }
|
||||||
|
float4 testgt(float4 x, float4 y) { return x > y; }
|
||||||
|
float4 testge(float4 x, float4 y) { return x >= y; }
|
||||||
|
float4 testle(float4 x, float4 y) { return x <= y; }
|
||||||
|
|
||||||
|
void testflt()
|
||||||
|
{
|
||||||
|
auto x = testgt([5,6,5,6], [4,6,8,7]);
|
||||||
|
assert((cast(int4)x).array == [-1,0,0,0]);
|
||||||
|
x = testlt([5,6,5,6], [4,6,8,7]);
|
||||||
|
assert((cast(int4)x).array == [0,0,-1,-1]);
|
||||||
|
x = testle([5,6,5,6], [4,6,8,7]);
|
||||||
|
assert((cast(int4)x).array == [0,-1,-1,-1]);
|
||||||
|
x = testge([5,6,5,6], [4,6,8,7]);
|
||||||
|
assert((cast(int4)x).array == [-1,-1,0,0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
double2 testlt(double2 x, double2 y) { return x < y; }
|
||||||
|
double2 testgt(double2 x, double2 y) { return x > y; }
|
||||||
|
double2 testge(double2 x, double2 y) { return x >= y; }
|
||||||
|
double2 testle(double2 x, double2 y) { return x <= y; }
|
||||||
|
|
||||||
|
void testdbl()
|
||||||
|
{
|
||||||
|
auto x = testgt([5.0,6.0], [4.0,6.0]);
|
||||||
|
assert((cast(long2)x).array == [-1L,0]);
|
||||||
|
x = testlt([5.0,6.0], [4.0,6.0]);
|
||||||
|
assert((cast(long2)x).array == [0L,0]);
|
||||||
|
x = testle([5.0,6.0], [4.0,6.0]);
|
||||||
|
assert((cast(long2)x).array == [0L,-1]);
|
||||||
|
x = testge([5.0,6.0], [4.0,6.0]);
|
||||||
|
assert((cast(long2)x).array == [-1L,-1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*****************************************/
|
||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
test21474();
|
test21474();
|
||||||
|
@ -160,6 +196,8 @@ int main()
|
||||||
test2();
|
test2();
|
||||||
test3();
|
test3();
|
||||||
testunscmp();
|
testunscmp();
|
||||||
|
testflt();
|
||||||
|
testdbl();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue