summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTanner Gooding <tagoo@outlook.com>2017-12-14 21:41:03 -0800
committerTanner Gooding <tagoo@outlook.com>2018-01-16 16:04:13 -0800
commit402550ca34e814d6fe8fc38c4f189d0aed82efeb (patch)
tree46bfc3a67c6fa6e67e2958fda7bc5cdf6ba771f5
parent1cb5722400d6a29117f02507249e499dd2b2bd9d (diff)
downloadcoreclr-402550ca34e814d6fe8fc38c4f189d0aed82efeb.tar.gz
coreclr-402550ca34e814d6fe8fc38c4f189d0aed82efeb.tar.bz2
coreclr-402550ca34e814d6fe8fc38c4f189d0aed82efeb.zip
Adding support for the SSE compare eq, gt, ge, lt, le, ne, ord, and unord intrinsics
-rw-r--r--src/jit/emitxarch.cpp17
-rw-r--r--src/jit/emitxarch.h1
-rw-r--r--src/jit/hwintrinsiccodegenxarch.cpp52
-rw-r--r--src/jit/hwintrinsicxarch.cpp12
4 files changed, 82 insertions, 0 deletions
diff --git a/src/jit/emitxarch.cpp b/src/jit/emitxarch.cpp
index 3b12cf8323..7282baa26d 100644
--- a/src/jit/emitxarch.cpp
+++ b/src/jit/emitxarch.cpp
@@ -5142,6 +5142,23 @@ void emitter::emitIns_SIMD_R_R_S(instruction ins, regNumber reg, regNumber reg1,
emitIns_R_S(ins, emitTypeSize(simdtype), reg, varx, offs);
}
}
+
+void emitter::emitIns_SIMD_R_R_R_I(
+ instruction ins, regNumber reg, regNumber reg1, regNumber reg2, int ival, var_types simdtype)
+{
+ if (UseVEXEncoding())
+ {
+ emitIns_R_R_R_I(ins, emitTypeSize(simdtype), reg, reg1, reg2, ival);
+ }
+ else
+ {
+ if (reg1 != reg)
+ {
+ emitIns_R_R(INS_movaps, emitTypeSize(simdtype), reg, reg1);
+ }
+ emitIns_R_R_I(ins, emitTypeSize(simdtype), reg, reg2, ival);
+ }
+}
#endif
/*****************************************************************************
diff --git a/src/jit/emitxarch.h b/src/jit/emitxarch.h
index 119ac0dc3e..e8097a491e 100644
--- a/src/jit/emitxarch.h
+++ b/src/jit/emitxarch.h
@@ -446,6 +446,7 @@ void emitIns_SIMD_R_R_C(
instruction ins, regNumber reg, regNumber reg1, CORINFO_FIELD_HANDLE fldHnd, int offs, var_types simdtype);
void emitIns_SIMD_R_R_R(instruction ins, regNumber reg, regNumber reg1, regNumber reg2, var_types simdtype);
void emitIns_SIMD_R_R_S(instruction ins, regNumber reg, regNumber reg1, int varx, int offs, var_types simdtype);
+void emitIns_SIMD_R_R_R_I(instruction ins, regNumber reg, regNumber reg1, regNumber reg2, int ival, var_types simdtype);
#endif
#if FEATURE_STACK_FP_X87
diff --git a/src/jit/hwintrinsiccodegenxarch.cpp b/src/jit/hwintrinsiccodegenxarch.cpp
index 7248e59286..64769b9be7 100644
--- a/src/jit/hwintrinsiccodegenxarch.cpp
+++ b/src/jit/hwintrinsiccodegenxarch.cpp
@@ -226,6 +226,58 @@ void CodeGen::genSSEIntrinsic(GenTreeHWIntrinsic* node)
emit->emitIns_SIMD_R_R_R(INS_andnps, targetReg, op1Reg, op2Reg, TYP_SIMD16);
break;
+ case NI_SSE_CompareEqual:
+ assert(baseType == TYP_FLOAT);
+ op2Reg = op2->gtRegNum;
+ emit->emitIns_SIMD_R_R_R_I(INS_cmpps, targetReg, op1Reg, op2Reg, 0, TYP_SIMD16);
+ break;
+
+ case NI_SSE_CompareGreaterThan:
+ case NI_SSE_CompareNotLessThanOrEqual:
+ assert(baseType == TYP_FLOAT);
+ op2Reg = op2->gtRegNum;
+ emit->emitIns_SIMD_R_R_R_I(INS_cmpps, targetReg, op1Reg, op2Reg, 6, TYP_SIMD16);
+ break;
+
+ case NI_SSE_CompareGreaterThanOrEqual:
+ case NI_SSE_CompareNotLessThan:
+ assert(baseType == TYP_FLOAT);
+ op2Reg = op2->gtRegNum;
+ emit->emitIns_SIMD_R_R_R_I(INS_cmpps, targetReg, op1Reg, op2Reg, 5, TYP_SIMD16);
+ break;
+
+ case NI_SSE_CompareLessThan:
+ case NI_SSE_CompareNotGreaterThanOrEqual:
+ assert(baseType == TYP_FLOAT);
+ op2Reg = op2->gtRegNum;
+ emit->emitIns_SIMD_R_R_R_I(INS_cmpps, targetReg, op1Reg, op2Reg, 1, TYP_SIMD16);
+ break;
+
+ case NI_SSE_CompareLessThanOrEqual:
+ case NI_SSE_CompareNotGreaterThan:
+ assert(baseType == TYP_FLOAT);
+ op2Reg = op2->gtRegNum;
+ emit->emitIns_SIMD_R_R_R_I(INS_cmpps, targetReg, op1Reg, op2Reg, 2, TYP_SIMD16);
+ break;
+
+ case NI_SSE_CompareNotEqual:
+ assert(baseType == TYP_FLOAT);
+ op2Reg = op2->gtRegNum;
+ emit->emitIns_SIMD_R_R_R_I(INS_cmpps, targetReg, op1Reg, op2Reg, 4, TYP_SIMD16);
+ break;
+
+ case NI_SSE_CompareOrdered:
+ assert(baseType == TYP_FLOAT);
+ op2Reg = op2->gtRegNum;
+ emit->emitIns_SIMD_R_R_R_I(INS_cmpps, targetReg, op1Reg, op2Reg, 7, TYP_SIMD16);
+ break;
+
+ case NI_SSE_CompareUnordered:
+ assert(baseType == TYP_FLOAT);
+ op2Reg = op2->gtRegNum;
+ emit->emitIns_SIMD_R_R_R_I(INS_cmpps, targetReg, op1Reg, op2Reg, 3, TYP_SIMD16);
+ break;
+
case NI_SSE_Divide:
assert(baseType == TYP_FLOAT);
op2Reg = op2->gtRegNum;
diff --git a/src/jit/hwintrinsicxarch.cpp b/src/jit/hwintrinsicxarch.cpp
index 0b656a65fc..fd1c41a03c 100644
--- a/src/jit/hwintrinsicxarch.cpp
+++ b/src/jit/hwintrinsicxarch.cpp
@@ -455,6 +455,18 @@ GenTree* Compiler::impSSEIntrinsic(NamedIntrinsic intrinsic,
case NI_SSE_Add:
case NI_SSE_And:
case NI_SSE_AndNot:
+ case NI_SSE_CompareEqual:
+ case NI_SSE_CompareGreaterThan:
+ case NI_SSE_CompareGreaterThanOrEqual:
+ case NI_SSE_CompareLessThan:
+ case NI_SSE_CompareLessThanOrEqual:
+ case NI_SSE_CompareNotEqual:
+ case NI_SSE_CompareNotGreaterThan:
+ case NI_SSE_CompareNotGreaterThanOrEqual:
+ case NI_SSE_CompareNotLessThan:
+ case NI_SSE_CompareNotLessThanOrEqual:
+ case NI_SSE_CompareOrdered:
+ case NI_SSE_CompareUnordered:
case NI_SSE_Divide:
case NI_SSE_Max:
case NI_SSE_Min: