@@ -1861,19 +1861,69 @@ bool emitter::TakesEvexPrefix(const instrDesc* id) const
18611861 }
18621862#endif // DEBUG
18631863
1864- if ((ins == INS_pslldq) || (ins == INS_psrldq ))
1864+ if (id->idHasMem( ))
18651865 {
1866- // The memory operand can only be encoded using the EVEX encoding
1867- return id->idHasMem();
1868- }
1866+ if ((ins == INS_pslldq) || (ins == INS_psrldq))
1867+ {
1868+ // The memory operand can only be encoded using the EVEX encoding
1869+ return true;
1870+ }
18691871
1870- if ((insTupleTypeInfo(ins) & INS_TT_MEM128) != 0)
1871- {
1872- assert((ins == INS_pslld) || (ins == INS_psllq) || (ins == INS_psllw) || (ins == INS_psrad) ||
1873- (ins == INS_psraw) || (ins == INS_psrld) || (ins == INS_psrlq) || (ins == INS_psrlw));
1872+ if ((insTupleTypeInfo(ins) & INS_TT_MEM128) != 0)
1873+ {
1874+ assert((ins == INS_pslld) || (ins == INS_psllq) || (ins == INS_psllw) || (ins == INS_psrad) ||
1875+ (ins == INS_psraw) || (ins == INS_psrld) || (ins == INS_psrlq) || (ins == INS_psrlw));
1876+
1877+ if (id->idHasMemAndCns())
1878+ {
1879+ // Memory operand with immediate can only be encoded using EVEX
1880+ return true;
1881+ }
1882+ }
1883+
1884+ if (id->idHasMemGen())
1885+ {
1886+ return false;
1887+ }
1888+
1889+ ssize_t dsp = 0;
1890+
1891+ if (id->idHasMemStk())
1892+ {
1893+ bool ebpBased = false;
1894+ int varNum = id->idAddr()->iiaLclVar.lvaVarNum();
1895+
1896+ dsp = emitComp->lvaFrameAddress(varNum, &ebpBased) + id->idAddr()->iiaLclVar.lvaOffset();
1897+
1898+ #if !FEATURE_FIXED_OUT_ARGS
1899+ if (!ebpBased)
1900+ {
1901+ // Adjust the offset by the amount currently pushed on the CPU stack
1902+ dsp += emitCurStackLvl;
1903+ }
1904+ #endif // !FEATURE_FIXED_OUT_ARGS
1905+ }
1906+ else
1907+ {
1908+ assert(id->idHasMemAdr());
1909+
1910+ if (id->idIsDspReloc())
1911+ {
1912+ // reloc cannot be compressed
1913+ return false;
1914+ }
18741915
1875- // Memory operand with immediate can only be encoded using EVEX
1876- return id->idHasMemAndCns();
1916+ dsp = emitGetInsAmdAny(id);
1917+ }
1918+
1919+ // We don't want to use compressed displacement if it already fit into a byte
1920+ bool dspInByte = (static_cast<int8_t>(dsp) == dsp);
1921+
1922+ if (!dspInByte)
1923+ {
1924+ dsp = TryEvexCompressDisp8Byte(id, dsp, &dspInByte);
1925+ return dspInByte;
1926+ }
18771927 }
18781928
18791929 return false;
@@ -17968,7 +18018,7 @@ BYTE* emitter::emitOutputLJ(insGroup* ig, BYTE* dst, instrDesc* i)
1796818018// Return Value:
1796918019// size in bytes.
1797018020//
17971- ssize_t emitter::GetInputSizeInBytes(instrDesc* id) const
18021+ ssize_t emitter::GetInputSizeInBytes(const instrDesc* id) const
1797218022{
1797318023 assert((unsigned)id->idIns() < ArrLen(CodeGenInterface::instInfo));
1797418024 insFlags inputSize = static_cast<insFlags>((CodeGenInterface::instInfo[id->idIns()] & Input_Mask));
@@ -18002,24 +18052,24 @@ ssize_t emitter::GetInputSizeInBytes(instrDesc* id) const
1800218052// compressed displacement value if dspInByte === TRUE.
1800318053// Original dsp otherwise.
1800418054//
18005- ssize_t emitter::TryEvexCompressDisp8Byte(instrDesc* id, ssize_t dsp, bool* dspInByte)
18055+ ssize_t emitter::TryEvexCompressDisp8Byte(const instrDesc* id, ssize_t dsp, bool* dspInByte) const
1800618056{
18007- assert(TakesEvexPrefix(id) || TakesApxExtendedEvexPrefix(id));
18057+ instruction ins = id->idIns();
18058+ assert(IsEvexEncodableInstruction(ins) || IsApxExtendedEvexInstruction(ins));
1800818059
18009- if (!hasTupleTypeInfo(id->idIns() ))
18060+ if (!hasTupleTypeInfo(ins ))
1801018061 {
1801118062 // After APX, some instructions with APX features will be promoted
1801218063 // to APX-EVEX, we will re-use the existing displacement emitting
1801318064 // path, but for those instructions with no tuple information,
1801418065 // APX-EVEX treat the scaling factor to be 1 constantly.
18015- instruction ins = id->idIns();
1801618066 assert(IsApxExtendedEvexInstruction(ins) || IsBMIInstruction(ins));
1801718067 *dspInByte = ((signed char)dsp == (ssize_t)dsp);
1801818068 return dsp;
1801918069 }
1802018070
18021- insTupleType tt = insTupleTypeInfo(id->idIns() );
18022- assert(hasTupleTypeInfo(id->idIns() ));
18071+ insTupleType tt = insTupleTypeInfo(ins );
18072+ assert(hasTupleTypeInfo(ins ));
1802318073
1802418074 // if dsp is 0, no need for all of this
1802518075 if (dsp == 0)
@@ -18038,9 +18088,7 @@ ssize_t emitter::TryEvexCompressDisp8Byte(instrDesc* id, ssize_t dsp, bool* dspI
1803818088 if ((tt & INS_TT_MEM128) != 0)
1803918089 {
1804018090 // These instructions can be one of two tuple types, so we need to find the right one
18041-
18042- instruction ins = id->idIns();
18043- insFormat insFmt = id->idInsFmt();
18091+ insFormat insFmt = id->idInsFmt();
1804418092
1804518093 if ((tt & INS_TT_FULL) != 0)
1804618094 {
0 commit comments