Merge pull request #8556 from Sintendo/bestrest

x64Emitter: Avoid 8-bit displacement when possible
This commit is contained in:
Tilka
2020-01-25 19:10:47 +00:00
committed by GitHub
3 changed files with 119 additions and 56 deletions

View File

@ -13,7 +13,6 @@
namespace Gen
{
// TODO(ector): Add EAX special casing, for ever so slightly smaller code.
struct NormalOpDef
{
u8 toRm8, toRm32, fromRm8, fromRm32, imm8, imm32, simm8, eaximm8, eaximm32, ext;
@ -270,67 +269,45 @@ void OpArg::WriteRest(XEmitter* emit, int extraBytes, X64Reg _operandReg,
return;
}
if (scale == 0)
if (scale == SCALE_NONE)
{
// Oh, no memory, Just a reg.
mod = 3; // 11
}
else if (scale >= SCALE_NOBASE_2 && scale <= SCALE_NOBASE_8)
{
SIB = true;
mod = 0;
_offsetOrBaseReg = 5;
// Always has 32-bit displacement
}
else
{
// Ah good, no scaling.
if (scale == SCALE_ATREG && !((_offsetOrBaseReg & 7) == 4 || (_offsetOrBaseReg & 7) == 5))
{
// Okay, we're good. No SIB necessary.
int ioff = (int)offset;
if (ioff == 0)
{
mod = 0;
}
else if (ioff < -128 || ioff > 127)
{
mod = 2; // 32-bit displacement
}
else
{
mod = 1; // 8-bit displacement
}
}
else if (scale >= SCALE_NOBASE_2 && scale <= SCALE_NOBASE_8)
if (scale != SCALE_ATREG)
{
SIB = true;
mod = 0;
_offsetOrBaseReg = 5;
}
else if ((_offsetOrBaseReg & 7) == 4)
{
// Special case for which SCALE_ATREG needs SIB
SIB = true;
ireg = _offsetOrBaseReg;
}
// Okay, we're fine. Just disp encoding.
// We need displacement. Which size?
int ioff = (int)(s64)offset;
if (ioff == 0 && (_offsetOrBaseReg & 7) != 5)
{
mod = 0; // No displacement
}
else if (ioff >= -128 && ioff <= 127)
{
mod = 1; // 8-bit displacement
}
else
{
if ((_offsetOrBaseReg & 7) == 4) // this would occupy the SIB encoding :(
{
// So we have to fake it with SIB encoding :(
SIB = true;
}
if (scale >= SCALE_1 && scale < SCALE_ATREG)
{
SIB = true;
}
if (scale == SCALE_ATREG && ((_offsetOrBaseReg & 7) == 4))
{
SIB = true;
ireg = _offsetOrBaseReg;
}
// Okay, we're fine. Just disp encoding.
// We need displacement. Which size?
int ioff = (int)(s64)offset;
if (ioff < -128 || ioff > 127)
{
mod = 2; // 32-bit displacement
}
else
{
mod = 1; // 8-bit displacement
}
mod = 2; // 32-bit displacement
}
}

View File

@ -313,11 +313,6 @@ inline u32 PtrOffset(const void* ptr, const void* base = nullptr)
return (u32)distance;
}
// usage: int a[]; ARRAY_OFFSET(a,10)
#define ARRAY_OFFSET(array, index) ((u32)((u64) & (array)[index] - (u64) & (array)[0]))
// usage: struct {int e;} s; STRUCT_OFFSET(s,e)
#define STRUCT_OFFSET(str, elem) ((u32)((u64) & (str).elem - (u64) & (str)))
struct FixupBranch
{
enum class Type