@@ -998,10 +998,12 @@ void CodeGen::genHWIntrinsic(GenTreeHWIntrinsic* node)
998998 break ;
999999 }
10001000
1001+ case InstructionSet_WAITPKG:
10011002 case InstructionSet_X86Base:
10021003 case InstructionSet_X86Base_X64:
1004+ case InstructionSet_X86Serialize:
10031005 {
1004- genX86BaseIntrinsic (node, instOptions);
1006+ genHWIntrinsicSpecial (node, instOptions);
10051007 break ;
10061008 }
10071009
@@ -1025,14 +1027,6 @@ void CodeGen::genHWIntrinsic(GenTreeHWIntrinsic* node)
10251027 break ;
10261028 }
10271029
1028- case InstructionSet_X86Serialize:
1029- case InstructionSet_X86Serialize_X64:
1030- {
1031- assert (instOptions == INS_OPTS_NONE);
1032- genX86SerializeIntrinsic (node);
1033- break ;
1034- }
1035-
10361030 default :
10371031 unreached ();
10381032 break ;
@@ -2362,12 +2356,12 @@ void CodeGen::genBaseIntrinsic(GenTreeHWIntrinsic* node, insOpts instOptions)
23622356}
23632357
23642358// ------------------------------------------------------------------------
2365- // genX86BaseIntrinsic : Generates the code for an X86 base hardware intrinsic node
2359+ // genHWIntrinsicSpecial : Generates the code for an special hardware intrinsic node
23662360//
23672361// Arguments:
23682362// node - The hardware intrinsic node
23692363//
2370- void CodeGen::genX86BaseIntrinsic (GenTreeHWIntrinsic* node, insOpts instOptions)
2364+ void CodeGen::genHWIntrinsicSpecial (GenTreeHWIntrinsic* node, insOpts instOptions)
23712365{
23722366 NamedIntrinsic intrinsicId = node->GetHWIntrinsicId ();
23732367 regNumber targetReg = node->GetRegNum ();
@@ -2450,6 +2444,7 @@ void CodeGen::genX86BaseIntrinsic(GenTreeHWIntrinsic* node, insOpts instOptions)
24502444 case NI_X86Base_Prefetch1:
24512445 case NI_X86Base_Prefetch2:
24522446 case NI_X86Base_PrefetchNonTemporal:
2447+ case NI_WAITPKG_SetUpUserLevelMonitor:
24532448 {
24542449 assert (baseType == TYP_UBYTE);
24552450 assert (instOptions == INS_OPTS_NONE);
@@ -2518,6 +2513,50 @@ void CodeGen::genX86BaseIntrinsic(GenTreeHWIntrinsic* node, insOpts instOptions)
25182513 break ;
25192514 }
25202515
2516+ case NI_X86Serialize_Serialize:
2517+ {
2518+ assert (instOptions == INS_OPTS_NONE);
2519+ assert (node->GetSimdBaseType () == TYP_UNKNOWN);
2520+ GetEmitter ()->emitIns (INS_serialize);
2521+ break ;
2522+ }
2523+
2524+ case NI_WAITPKG_TimedPause:
2525+ case NI_WAITPKG_WaitForUserLevelMonitor:
2526+ {
2527+ assert (node->GetSimdBaseType () == TYP_INT);
2528+
2529+ assert (node->GetOperandCount () == 3 );
2530+ assert (instOptions == INS_OPTS_NONE);
2531+
2532+ GenTree* op1 = node->Op (1 );
2533+ GenTree* op2 = node->Op (2 );
2534+ GenTree* op3 = node->Op (3 );
2535+
2536+ instruction ins = HWIntrinsicInfo::lookupIns (intrinsicId, TYP_INT, compiler);
2537+
2538+ regNumber op1Reg = op1->GetRegNum ();
2539+ regNumber op2Reg = op2->GetRegNum ();
2540+ regNumber op3Reg = op3->GetRegNum ();
2541+
2542+ emitAttr attr = emitTypeSize (TYP_INT);
2543+
2544+ // op1: free, op2: EDX, op3: EAX
2545+
2546+ assert (op1Reg != REG_EDX);
2547+ assert (op1Reg != REG_EAX);
2548+
2549+ assert (op2Reg != REG_EAX);
2550+ assert (op3Reg != REG_EDX);
2551+
2552+ emit->emitIns_Mov (INS_mov, attr, REG_EDX, op2Reg, /* canSkip */ true );
2553+ emit->emitIns_Mov (INS_mov, attr, REG_EAX, op3Reg, /* canSkip */ true );
2554+
2555+ // emit the TPAUSE/UMWAIT instruction
2556+ emit->emitIns_R (ins, attr, op1Reg);
2557+ break ;
2558+ }
2559+
25212560 default :
25222561 unreached ();
25232562 break ;
@@ -3916,33 +3955,4 @@ void CodeGen::genXCNTIntrinsic(GenTreeHWIntrinsic* node, instruction ins)
39163955 genHWIntrinsic_R_RM (node, ins, emitTypeSize (node->TypeGet ()), targetReg, op1, INS_OPTS_NONE);
39173956}
39183957
3919- // ------------------------------------------------------------------------
3920- // genX86SerializeIntrinsic: Generates the code for an X86 serialize hardware intrinsic node
3921- //
3922- // Arguments:
3923- // node - The hardware intrinsic node
3924- //
3925- void CodeGen::genX86SerializeIntrinsic (GenTreeHWIntrinsic* node)
3926- {
3927- NamedIntrinsic intrinsicId = node->GetHWIntrinsicId ();
3928-
3929- genConsumeMultiOpOperands (node);
3930-
3931- switch (intrinsicId)
3932- {
3933- case NI_X86Serialize_Serialize:
3934- {
3935- assert (node->GetSimdBaseType () == TYP_UNKNOWN);
3936- GetEmitter ()->emitIns (INS_serialize);
3937- break ;
3938- }
3939-
3940- default :
3941- unreached ();
3942- break ;
3943- }
3944-
3945- genProduceReg (node);
3946- }
3947-
39483958#endif // FEATURE_HW_INTRINSICS
0 commit comments