@@ -5620,7 +5620,7 @@ void emitter::emitIns_R(instruction ins, emitAttr attr, regNumber reg)
5620
5620
// varNum - the variable on the stack to use as a base;
5621
5621
// offset - the offset from the varNum;
5622
5622
// dataReg - the src reg with SIMD12 value;
5623
- // tmpRegProvider - a tree to grab a tmp reg from if needed.
5623
+ // tmpRegProvider - a tree to grab a tmp reg from if needed (can be null) .
5624
5624
//
5625
5625
void emitter::emitStoreSimd12ToLclOffset(unsigned varNum, unsigned offset, regNumber dataReg, GenTree* tmpRegProvider)
5626
5626
{
@@ -5635,7 +5635,7 @@ void emitter::emitStoreSimd12ToLclOffset(unsigned varNum, unsigned offset, regNu
5635
5635
// Extract and store upper 4 bytes
5636
5636
emitIns_S_R_I(INS_extractps, EA_16BYTE, varNum, offset + 8, dataReg, 2);
5637
5637
}
5638
- else
5638
+ else if (tmpRegProvider != nullptr)
5639
5639
{
5640
5640
regNumber tmpReg = codeGen->internalRegisters.GetSingle(tmpRegProvider);
5641
5641
assert(isFloatReg(tmpReg));
@@ -5646,6 +5646,19 @@ void emitter::emitStoreSimd12ToLclOffset(unsigned varNum, unsigned offset, regNu
5646
5646
// Store upper 4 bytes
5647
5647
emitIns_S_R(INS_movss, EA_4BYTE, tmpReg, varNum, offset + 8);
5648
5648
}
5649
+ else
5650
+ {
5651
+ // We don't have temp regs - let's do two shuffles then
5652
+
5653
+ // [0,1,2,3] -> [2,3,0,1]
5654
+ emitIns_R_R_I(INS_pshufd, EA_16BYTE, dataReg, dataReg, 78);
5655
+
5656
+ // Store upper 4 bytes
5657
+ emitIns_S_R(INS_movss, EA_4BYTE, dataReg, varNum, offset + 8);
5658
+
5659
+ // Restore dataReg to its previous state: [2,3,0,1] -> [0,1,2,3]
5660
+ emitIns_R_R_I(INS_pshufd, EA_16BYTE, dataReg, dataReg, 78);
5661
+ }
5649
5662
}
5650
5663
#endif // FEATURE_SIMD
5651
5664
0 commit comments