Skip to content

Commit 01e4d44

Browse files
Adds ccmp logic into emitter backend. (#112153)
* Adds `ccmp` logic into emitter backend. * Review edits * Small fix.
1 parent 5608cd9 commit 01e4d44

File tree

9 files changed

+384
-5
lines changed

9 files changed

+384
-5
lines changed

src/coreclr/jit/codegen.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -708,6 +708,7 @@ class CodeGen final : public CodeGenInterface
708708
void genAmd64EmitterUnitTestsSse2();
709709
void genAmd64EmitterUnitTestsApx();
710710
void genAmd64EmitterUnitTestsAvx10v2();
711+
void genAmd64EmitterUnitTestsCCMP();
711712
#endif
712713

713714
#endif // defined(DEBUG)

src/coreclr/jit/codegenlinear.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2716,6 +2716,10 @@ void CodeGen::genEmitterUnitTests()
27162716
{
27172717
genAmd64EmitterUnitTestsAvx10v2();
27182718
}
2719+
if (unitTestSectionAll || (strstr(unitTestSection, "ccmp") != nullptr))
2720+
{
2721+
genAmd64EmitterUnitTestsCCMP();
2722+
}
27192723

27202724
#elif defined(TARGET_ARM64)
27212725
if (unitTestSectionAll || (strstr(unitTestSection, "general") != nullptr))

src/coreclr/jit/codegenxarch.cpp

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9490,6 +9490,84 @@ void CodeGen::genAmd64EmitterUnitTestsAvx10v2()
94909490
theEmitter->emitIns_R_R(INS_vmovw, EA_16BYTE, REG_XMM0, REG_XMM1);
94919491
}
94929492

9493+
/*****************************************************************************
9494+
* Unit tests for the CCMP instructions.
9495+
*/
9496+
9497+
void CodeGen::genAmd64EmitterUnitTestsCCMP()
9498+
{
9499+
emitter* theEmitter = GetEmitter();
9500+
genDefineTempLabel(genCreateTempLabel());
9501+
9502+
// ============
9503+
// Test RR form
9504+
// ============
9505+
9506+
// Test all sizes
9507+
theEmitter->emitIns_R_R(INS_ccmpe, EA_4BYTE, REG_RAX, REG_RCX, INS_OPTS_EVEX_dfv_cf);
9508+
theEmitter->emitIns_R_R(INS_ccmpe, EA_8BYTE, REG_RAX, REG_RCX, INS_OPTS_EVEX_dfv_cf);
9509+
theEmitter->emitIns_R_R(INS_ccmpe, EA_2BYTE, REG_RAX, REG_RCX, INS_OPTS_EVEX_dfv_cf);
9510+
theEmitter->emitIns_R_R(INS_ccmpe, EA_1BYTE, REG_RAX, REG_RCX, INS_OPTS_EVEX_dfv_cf);
9511+
9512+
// Test all CC codes
9513+
for (uint32_t ins = INS_FIRST_CCMP_INSTRUCTION + 1; ins < INS_LAST_CCMP_INSTRUCTION; ins++)
9514+
{
9515+
theEmitter->emitIns_R_R((instruction)ins, EA_4BYTE, REG_RAX, REG_RCX, INS_OPTS_EVEX_dfv_cf);
9516+
}
9517+
9518+
// Test all dfv
9519+
for (int i = 0; i < 16; i++)
9520+
{
9521+
theEmitter->emitIns_R_R(INS_ccmpe, EA_4BYTE, REG_RAX, REG_RCX, (insOpts)(i << INS_OPTS_EVEX_dfv_byte_offset));
9522+
}
9523+
9524+
// ============
9525+
// Test RS form
9526+
// ============
9527+
9528+
// Test all sizes
9529+
theEmitter->emitIns_R_S(INS_ccmpe, EA_4BYTE, REG_RAX, 0, 0, INS_OPTS_EVEX_dfv_cf);
9530+
theEmitter->emitIns_R_S(INS_ccmpe, EA_8BYTE, REG_RAX, 0, 0, INS_OPTS_EVEX_dfv_cf);
9531+
theEmitter->emitIns_R_S(INS_ccmpe, EA_2BYTE, REG_RAX, 0, 0, INS_OPTS_EVEX_dfv_cf);
9532+
theEmitter->emitIns_R_S(INS_ccmpe, EA_1BYTE, REG_RAX, 0, 0, INS_OPTS_EVEX_dfv_cf);
9533+
9534+
// Test all CC codes
9535+
for (uint32_t ins = INS_FIRST_CCMP_INSTRUCTION + 1; ins < INS_LAST_CCMP_INSTRUCTION; ins++)
9536+
{
9537+
theEmitter->emitIns_R_S((instruction)ins, EA_4BYTE, REG_RAX, 0, 0, INS_OPTS_EVEX_dfv_cf);
9538+
}
9539+
9540+
// Test all dfv
9541+
for (int i = 0; i < 16; i++)
9542+
{
9543+
theEmitter->emitIns_R_S(INS_ccmpe, EA_4BYTE, REG_RAX, 0, 0, (insOpts)(i << INS_OPTS_EVEX_dfv_byte_offset));
9544+
}
9545+
9546+
// ============
9547+
// Test RI form (test small and large sizes and constants)
9548+
// ============
9549+
9550+
theEmitter->emitIns_R_I(INS_ccmpe, EA_4BYTE, REG_RAX, 123, INS_OPTS_EVEX_dfv_cf);
9551+
theEmitter->emitIns_R_I(INS_ccmpe, EA_4BYTE, REG_RAX, 270, INS_OPTS_EVEX_dfv_cf);
9552+
9553+
theEmitter->emitIns_R_I(INS_ccmpe, EA_8BYTE, REG_RAX, 123, INS_OPTS_EVEX_dfv_cf);
9554+
theEmitter->emitIns_R_I(INS_ccmpe, EA_8BYTE, REG_RAX, 270, INS_OPTS_EVEX_dfv_cf);
9555+
9556+
theEmitter->emitIns_R_I(INS_ccmpe, EA_2BYTE, REG_RAX, 123, INS_OPTS_EVEX_dfv_cf);
9557+
theEmitter->emitIns_R_I(INS_ccmpe, EA_2BYTE, REG_RAX, 270, INS_OPTS_EVEX_dfv_cf);
9558+
9559+
theEmitter->emitIns_R_I(INS_ccmpe, EA_1BYTE, REG_RAX, 123, INS_OPTS_EVEX_dfv_cf);
9560+
theEmitter->emitIns_R_I(INS_ccmpe, EA_1BYTE, REG_RAX, 270, INS_OPTS_EVEX_dfv_cf);
9561+
9562+
// ============
9563+
// Test RC form
9564+
// ============
9565+
9566+
CORINFO_FIELD_HANDLE hnd = theEmitter->emitFltOrDblConst(1.0f, EA_4BYTE);
9567+
theEmitter->emitIns_R_C(INS_ccmpe, EA_4BYTE, REG_RAX, hnd, 0, INS_OPTS_EVEX_dfv_cf);
9568+
theEmitter->emitIns_R_C(INS_ccmpe, EA_4BYTE, REG_RAX, hnd, 4, INS_OPTS_EVEX_dfv_cf);
9569+
}
9570+
94939571
#endif // defined(DEBUG) && defined(TARGET_AMD64)
94949572

94959573
#ifdef PROFILING_SUPPORTED

src/coreclr/jit/emit.h

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -803,6 +803,9 @@ class emitter
803803
#define _idEvexNdContext _idCustom5 /* bits used for the APX-EVEX.nd context for promoted legacy instructions */
804804
#define _idEvexNfContext _idCustom6 /* bits used for the APX-EVEX.nf context for promoted legacy/vex instructions */
805805

806+
// We repurpose 4 bits for the default flag value bits for ccmp instructions.
807+
#define _idEvexDFV (_idCustom4 << 3) | (_idCustom3 << 2) | (_idCustom2 << 1) | _idCustom1
808+
806809
// In certian cases, we do not allow instructions to be promoted to APX-EVEX.
807810
// e.g. instructions like add/and/or/inc/dec can be used with LOCK prefix, but cannot be prefixed by LOCK and
808811
// EVEX together.
@@ -1753,6 +1756,23 @@ class emitter
17531756
assert(!idIsNoApxEvexPromotion());
17541757
_idNoApxEvexXPromotion = 1;
17551758
}
1759+
1760+
unsigned idGetEvexDFV() const
1761+
{
1762+
return _idEvexDFV;
1763+
}
1764+
1765+
void idSetEvexDFV(insOpts instOptions)
1766+
{
1767+
unsigned value = static_cast<unsigned>((instOptions & INS_OPTS_EVEX_dfv_MASK) >> 8);
1768+
1769+
_idCustom1 = ((value >> 0) & 1);
1770+
_idCustom2 = ((value >> 1) & 1);
1771+
_idCustom3 = ((value >> 2) & 1);
1772+
_idCustom4 = ((value >> 3) & 1);
1773+
1774+
assert(value == idGetEvexDFV());
1775+
}
17561776
#endif
17571777

17581778
#ifdef TARGET_ARMARCH

0 commit comments

Comments
 (0)