Skip to content

Commit

Permalink
Merge pull request #6699 from BradleyWood/disp8xnfix
Browse files Browse the repository at this point in the history
x86: Fix EVEX mem-ref displacement
  • Loading branch information
0xdaryl authored Sep 15, 2022
2 parents 38e2433 + c28f06c commit b1be89c
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 27 deletions.
42 changes: 28 additions & 14 deletions compiler/x/codegen/OMRMemoryReference.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1420,6 +1420,8 @@ OMR::X86::MemoryReference::generateBinaryEncoding(
self()->isForceWideDisplacement()) ? 4 : 0);

intptr_t displacement;
uint8_t displacementDivisor = 16;
bool isEvex = true;

uint8_t *cursor = modRM;
TR::RealRegister *base = NULL;
Expand All @@ -1428,6 +1430,26 @@ OMR::X86::MemoryReference::generateBinaryEncoding(
TR::Symbol *symbol;
uint8_t *immediateCursor = 0;

switch (containingInstruction->getEncodingMethod())
{
case OMR::X86::EVEX_L128:
break;
case OMR::X86::EVEX_L256:
displacementDivisor = 32;
break;
case OMR::X86::EVEX_L512:
displacementDivisor = 64;
break;
case OMR::X86::Default:
displacementDivisor = containingInstruction->getOpCode().info().isEvex256() ? 32 : displacementDivisor;
displacementDivisor = containingInstruction->getOpCode().info().isEvex512() ? 64 : displacementDivisor;
isEvex = containingInstruction->getOpCode().info().isEvex();
break;
default:
isEvex = false;
break;
}

switch (addressTypes)
{
case 1:
Expand Down Expand Up @@ -1641,15 +1663,11 @@ OMR::X86::MemoryReference::generateBinaryEncoding(
displacement = self()->getDisplacement();
TR_ASSERT(IS_32BIT_SIGNED(displacement), "64-bit displacement should have been replaced in TR_AMD64MemoryReference::generateBinaryEncoding");

uint8_t divisor = 16;
divisor = containingInstruction->getOpCode().info().isEvex256() ? 32 : divisor;
divisor = containingInstruction->getOpCode().info().isEvex512() ? 64 : divisor;

if (!isForceWideDisplacement() && containingInstruction->getOpCode().info().isEvex() && displacement % divisor == 0 && IS_8BIT_SIGNED(displacement / divisor))
if (!isForceWideDisplacement() && isEvex && (displacement % displacementDivisor) == 0 && IS_8BIT_SIGNED(displacement / displacementDivisor))
{
displacement /= divisor;
displacement /= displacementDivisor;
}
else if (containingInstruction->getOpCode().info().isEvex())
else if (isEvex)
{
setForceWideDisplacement();
}
Expand Down Expand Up @@ -1716,15 +1734,11 @@ OMR::X86::MemoryReference::generateBinaryEncoding(

TR_ASSERT(IS_32BIT_SIGNED(displacement), "64-bit displacement should have been replaced in TR_AMD64MemoryReference::generateBinaryEncoding");

uint8_t divisor = 16;
divisor = containingInstruction->getOpCode().info().isEvex256() ? 32 : divisor;
divisor = containingInstruction->getOpCode().info().isEvex512() ? 64 : divisor;

if (!isForceWideDisplacement() && containingInstruction->getOpCode().info().isEvex() && displacement % divisor == 0 && IS_8BIT_SIGNED(displacement / divisor))
if (!isForceWideDisplacement() && isEvex && (displacement % displacementDivisor) == 0 && IS_8BIT_SIGNED(displacement / displacementDivisor))
{
displacement /= divisor;
displacement /= displacementDivisor;
}
else if (containingInstruction->getOpCode().info().isEvex())
else if (isEvex)
{
setForceWideDisplacement();
}
Expand Down
32 changes: 19 additions & 13 deletions fvtest/compilerunittest/x/BinaryEncoder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -706,16 +706,22 @@ TEST_P(XRegMemEncEncodingTest, encode) {
}

INSTANTIATE_TEST_CASE_P(X86RegMemEnc, XRegMemEncEncodingTest, ::testing::ValuesIn(*TRTest::MakeVector<std::tuple<TR::InstOpCode::Mnemonic, TR::RealRegister::RegNum, TR::RealRegister::RegNum, int32_t, OMR::X86::Encoding, TRTest::BinaryInstruction>>(
std::make_tuple(TR::InstOpCode::MOVDQURegMem, TR::RealRegister::xmm1, TR::RealRegister::ecx, 0x0, OMR::X86::Legacy, "f30f6f09"),
std::make_tuple(TR::InstOpCode::MOVDQURegMem, TR::RealRegister::xmm1, TR::RealRegister::ecx, 0x0, OMR::X86::VEX_L128, "c5fa6f09"),
std::make_tuple(TR::InstOpCode::MOVDQURegMem, TR::RealRegister::xmm1, TR::RealRegister::ecx, 0x0, OMR::X86::VEX_L256, "c5fe6f09"),
std::make_tuple(TR::InstOpCode::MOVDQURegMem, TR::RealRegister::xmm1, TR::RealRegister::ecx, 0x0, OMR::X86::EVEX_L128, "62f17e086f09"),
std::make_tuple(TR::InstOpCode::MOVDQURegMem, TR::RealRegister::xmm10, TR::RealRegister::eax, 0x0, OMR::X86::EVEX_L256, "62717e286f10"),
std::make_tuple(TR::InstOpCode::MOVDQURegMem, TR::RealRegister::xmm10, TR::RealRegister::eax, 0x0, OMR::X86::EVEX_L512, "62717e486f10"),
std::make_tuple(TR::InstOpCode::VSQRTPDRegMem, TR::RealRegister::xmm1, TR::RealRegister::ecx, 0x8, OMR::X86::Legacy, "66480f514908"),
std::make_tuple(TR::InstOpCode::VSQRTPDRegMem, TR::RealRegister::xmm1, TR::RealRegister::ecx, 0x8, OMR::X86::VEX_L128, "c4e1f9514908"),
std::make_tuple(TR::InstOpCode::VSQRTPDRegMem, TR::RealRegister::xmm10, TR::RealRegister::eax, 0x0, OMR::X86::VEX_L256, "c461fd5110"),
std::make_tuple(TR::InstOpCode::VSQRTPDRegMem, TR::RealRegister::xmm10, TR::RealRegister::eax, 0x0, OMR::X86::EVEX_L128, "6271fd085110"),
std::make_tuple(TR::InstOpCode::VSQRTPDRegMem, TR::RealRegister::xmm10, TR::RealRegister::eax, 0x0, OMR::X86::EVEX_L256, "6271fd285110"),
std::make_tuple(TR::InstOpCode::VSQRTPDRegMem, TR::RealRegister::xmm10, TR::RealRegister::eax, 0x0, OMR::X86::EVEX_L512, "6271fd485110")
)));
std::make_tuple(TR::InstOpCode::MOVDQURegMem, TR::RealRegister::xmm1, TR::RealRegister::ecx, 0x0, OMR::X86::Legacy, "f30f6f09"),
std::make_tuple(TR::InstOpCode::MOVDQURegMem, TR::RealRegister::xmm1, TR::RealRegister::ecx, 0x0, OMR::X86::VEX_L128, "c5fa6f09"),
std::make_tuple(TR::InstOpCode::MOVDQURegMem, TR::RealRegister::xmm1, TR::RealRegister::ecx, 0x0, OMR::X86::VEX_L256, "c5fe6f09"),
std::make_tuple(TR::InstOpCode::MOVDQURegMem, TR::RealRegister::xmm1, TR::RealRegister::ecx, 0x0, OMR::X86::EVEX_L128, "62f17e086f09"),
std::make_tuple(TR::InstOpCode::MOVDQURegMem, TR::RealRegister::xmm10, TR::RealRegister::eax, 0x0, OMR::X86::EVEX_L256, "62717e286f10"),
std::make_tuple(TR::InstOpCode::MOVDQURegMem, TR::RealRegister::xmm10, TR::RealRegister::eax, 0x0, OMR::X86::EVEX_L512, "62717e486f10"),
std::make_tuple(TR::InstOpCode::VSQRTPDRegMem, TR::RealRegister::xmm1, TR::RealRegister::ecx, 0x8, OMR::X86::Legacy, "66480f514908"),
std::make_tuple(TR::InstOpCode::VSQRTPDRegMem, TR::RealRegister::xmm1, TR::RealRegister::ecx, 0x8, OMR::X86::VEX_L128, "c4e1f9514908"),
std::make_tuple(TR::InstOpCode::VSQRTPDRegMem, TR::RealRegister::xmm10, TR::RealRegister::eax, 0x0, OMR::X86::VEX_L256, "c461fd5110"),
std::make_tuple(TR::InstOpCode::VSQRTPDRegMem, TR::RealRegister::xmm10, TR::RealRegister::eax, 0x0, OMR::X86::EVEX_L128, "6271fd085110"),
std::make_tuple(TR::InstOpCode::VSQRTPDRegMem, TR::RealRegister::xmm10, TR::RealRegister::eax, 0x10, OMR::X86::EVEX_L128, "6271fd08515001"),
std::make_tuple(TR::InstOpCode::VSQRTPDRegMem, TR::RealRegister::xmm10, TR::RealRegister::eax, 0x1, OMR::X86::EVEX_L128, "6271fd08519001000000"),
std::make_tuple(TR::InstOpCode::VSQRTPDRegMem, TR::RealRegister::xmm10, TR::RealRegister::eax, 0x0, OMR::X86::EVEX_L256, "6271fd285110"),
std::make_tuple(TR::InstOpCode::VSQRTPDRegMem, TR::RealRegister::xmm10, TR::RealRegister::eax, 0x20, OMR::X86::EVEX_L256, "6271fd28515001"),
std::make_tuple(TR::InstOpCode::VSQRTPDRegMem, TR::RealRegister::xmm10, TR::RealRegister::eax, 0x2, OMR::X86::EVEX_L256, "6271fd28519002000000"),
std::make_tuple(TR::InstOpCode::VSQRTPDRegMem, TR::RealRegister::xmm10, TR::RealRegister::eax, 0x0, OMR::X86::EVEX_L512, "6271fd485110"),
std::make_tuple(TR::InstOpCode::VSQRTPDRegMem, TR::RealRegister::xmm10, TR::RealRegister::eax, 0x4, OMR::X86::EVEX_L512, "6271fd48519004000000"),
std::make_tuple(TR::InstOpCode::VSQRTPDRegMem, TR::RealRegister::xmm10, TR::RealRegister::eax, 0x40, OMR::X86::EVEX_L512, "6271fd48515001")
)));

0 comments on commit b1be89c

Please sign in to comment.