mirror of
https://github.com/dlang/dmd.git
synced 2025-04-26 21:21:48 +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);
|
||||
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);
|
||||
if (retregs != *pretregs)
|
||||
fixresult(cdb,e,retregs,pretregs);
|
||||
|
@ -1121,6 +1139,13 @@ private opcode_t xmmoperator(tym_t tym, OPER oper)
|
|||
case TYdouble:
|
||||
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);
|
||||
}
|
||||
break;
|
||||
|
|
|
@ -1821,24 +1821,14 @@ elem* toElem(Expression e, IRState *irs)
|
|||
}
|
||||
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* e2 = toElem(ce.e2, irs);
|
||||
|
||||
elem* ex;
|
||||
if (swap)
|
||||
tym_t tym = totym(ce.type);
|
||||
elem* ex; // store side effects in ex
|
||||
|
||||
// swap operands
|
||||
void swapOps()
|
||||
{
|
||||
// put side effects of e1 into ex
|
||||
if (el_sideeffect(e1) && e2.Eoper != OPconst)
|
||||
|
@ -1853,7 +1843,49 @@ elem* toElem(Expression e, IRState *irs)
|
|||
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())
|
||||
{
|
||||
|
|
|
@ -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()
|
||||
{
|
||||
test21474();
|
||||
|
@ -160,6 +196,8 @@ int main()
|
|||
test2();
|
||||
test3();
|
||||
testunscmp();
|
||||
testflt();
|
||||
testdbl();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue