@@ -5648,6 +5648,43 @@ void emitter::emitIns_R(instruction ins, emitAttr attr, regNumber reg)
5648
5648
emitAdjustStackDepthPushPop(ins);
5649
5649
}
5650
5650
5651
+ #if defined(FEATURE_SIMD)
5652
+ //-----------------------------------------------------------------------------------
5653
+ // emitStoreSimd12ToLclOffset: store SIMD12 value from dataReg to varNum+offset.
5654
+ //
5655
+ // Arguments:
5656
+ // varNum - the variable on the stack to use as a base;
5657
+ // offset - the offset from the varNum;
5658
+ // dataReg - the src reg with SIMD12 value;
5659
+ // tmpRegProvider - a tree to grab a tmp reg from if needed.
5660
+ //
5661
+ void emitter::emitStoreSimd12ToLclOffset(unsigned varNum, unsigned offset, regNumber dataReg, GenTree* tmpRegProvider)
5662
+ {
5663
+ assert(varNum != BAD_VAR_NUM);
5664
+ assert(isFloatReg(dataReg));
5665
+
5666
+ // Store lower 8 bytes
5667
+ emitIns_S_R(INS_movsd_simd, EA_8BYTE, dataReg, varNum, offset);
5668
+
5669
+ if (emitComp->compOpportunisticallyDependsOn(InstructionSet_SSE41))
5670
+ {
5671
+ // Extract and store upper 4 bytes
5672
+ emitIns_S_R_I(INS_extractps, EA_16BYTE, varNum, offset + 8, dataReg, 2);
5673
+ }
5674
+ else
5675
+ {
5676
+ regNumber tmpReg = tmpRegProvider->GetSingleTempReg();
5677
+ assert(isFloatReg(tmpReg));
5678
+
5679
+ // Extract upper 4 bytes from data
5680
+ emitIns_R_R(INS_movhlps, EA_16BYTE, tmpReg, dataReg);
5681
+
5682
+ // Store upper 4 bytes
5683
+ emitIns_S_R(INS_movss, EA_4BYTE, tmpReg, varNum, offset + 8);
5684
+ }
5685
+ }
5686
+ #endif // FEATURE_SIMD
5687
+
5651
5688
/*****************************************************************************
5652
5689
*
5653
5690
* Add an instruction referencing a register and a constant.
0 commit comments