Skip to content

Commit 5344cbd

Browse files
committed
Allow compressed displacement to be used when profitable
1 parent c12e876 commit 5344cbd

File tree

2 files changed

+70
-22
lines changed

2 files changed

+70
-22
lines changed

src/coreclr/jit/emitxarch.cpp

Lines changed: 68 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -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
{

src/coreclr/jit/emitxarch.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -652,7 +652,7 @@ bool hasVexOrEvexPrefix(code_t code)
652652
return (hasVexPrefix(code) || hasEvexPrefix(code));
653653
}
654654

655-
ssize_t TryEvexCompressDisp8Byte(instrDesc* id, ssize_t dsp, bool* dspInByte);
655+
ssize_t TryEvexCompressDisp8Byte(const instrDesc* id, ssize_t dsp, bool* dspInByte) const;
656656

657657
//------------------------------------------------------------------------
658658
// codeEvexMigrationCheck: Temporary check to use when adding EVEX codepaths
@@ -670,7 +670,7 @@ bool codeEvexMigrationCheck(code_t code)
670670
return hasEvexPrefix(code);
671671
}
672672

673-
ssize_t GetInputSizeInBytes(instrDesc* id) const;
673+
ssize_t GetInputSizeInBytes(const instrDesc* id) const;
674674

675675
bool containsAVXInstruction = false;
676676
bool ContainsAVX()

0 commit comments

Comments
 (0)