diff options
author | Tanner Gooding <tagoo@outlook.com> | 2017-12-14 21:41:03 -0800 |
---|---|---|
committer | Tanner Gooding <tagoo@outlook.com> | 2018-01-16 16:04:13 -0800 |
commit | 402550ca34e814d6fe8fc38c4f189d0aed82efeb (patch) | |
tree | 46bfc3a67c6fa6e67e2958fda7bc5cdf6ba771f5 | |
parent | 1cb5722400d6a29117f02507249e499dd2b2bd9d (diff) | |
download | coreclr-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.cpp | 17 | ||||
-rw-r--r-- | src/jit/emitxarch.h | 1 | ||||
-rw-r--r-- | src/jit/hwintrinsiccodegenxarch.cpp | 52 | ||||
-rw-r--r-- | src/jit/hwintrinsicxarch.cpp | 12 |
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: |