Skip to content

Commit

Permalink
Merge pull request #7564 from BradleyWood/reg_encoding
Browse files Browse the repository at this point in the history
x86: Fix register field encoding in VEX/EVEX prefix
  • Loading branch information
0xdaryl authored Dec 7, 2024
2 parents b893b2b + ca71041 commit 96d6a1d
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 32 deletions.
32 changes: 16 additions & 16 deletions compiler/x/amd64/codegen/OMRRealRegister.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -256,7 +256,7 @@ class OMR_EXTENSIBLE RealRegister : public OMR::X86::RealRegister
*/
void setRegisterFieldInVEX(uint8_t *opcodeByte)
{
*opcodeByte ^= ((_fullRegisterBinaryEncodings[_registerNumber].needsRexForByte << 3) | _fullRegisterBinaryEncodings[_registerNumber].id) << 3; // vvvv is in bits 3-6 of last byte of VEX
*opcodeByte ^= ((_fullRegisterBinaryEncodings[_registerNumber].needsRexPlusRXB << 3) | _fullRegisterBinaryEncodings[_registerNumber].id) << 3; // vvvv is in bits 3-6 of last byte of VEX
}

void setMaskRegisterInEvex(uint8_t *evex, bool zero = false)
Expand All @@ -265,11 +265,11 @@ class OMR_EXTENSIBLE RealRegister : public OMR::X86::RealRegister
*evex = (*evex & 0xf8) | (0x7 & regNum) | (zero ? 0x80 : 0);
}

void setSourceRegisterFieldInEVEX(uint8_t *opcodeByte)
void setSourceRegisterFieldInEVEX(uint8_t *evexP0)
{
uint8_t regNum = ((_fullRegisterBinaryEncodings[_registerNumber].needsRexForByte << 3) | _fullRegisterBinaryEncodings[_registerNumber].id);
uint8_t regNum = ((_fullRegisterBinaryEncodings[_registerNumber].needsRexPlusRXB << 3) | _fullRegisterBinaryEncodings[_registerNumber].id);
uint8_t bits = 0;
*opcodeByte &= 0x9F;
*evexP0 &= 0x9F;

if (regNum & 0x10)
{
Expand All @@ -281,29 +281,29 @@ class OMR_EXTENSIBLE RealRegister : public OMR::X86::RealRegister
bits |= 0x2;
}

*opcodeByte |= (~bits & 0x6) << 4;
*evexP0 |= (~bits & 0x6) << 4;
}

void setSource2ndRegisterFieldInEVEX(uint8_t *opcodeByte)
void setSource2ndRegisterFieldInEVEX(uint8_t *evexP1)
{
uint8_t regNum = ((_fullRegisterBinaryEncodings[_registerNumber].needsRexForByte << 3) | _fullRegisterBinaryEncodings[_registerNumber].id);
uint8_t regNum = ((_fullRegisterBinaryEncodings[_registerNumber].needsRexPlusRXB << 3) | _fullRegisterBinaryEncodings[_registerNumber].id);

*opcodeByte &= 0x87; // zero out vvvv bits
*opcodeByte |= (~(regNum << 3)) & 0x78;
uint8_t *evexP1 = opcodeByte + 1;
*evexP1 &= 0xf7;
*evexP1 &= 0x87; // zero out vvvv bits
*evexP1 |= (~(regNum << 3)) & 0x78;
uint8_t *evexP2 = evexP1 + 1;
*evexP2 &= 0xf7;

if (!(regNum & 0x10))
{
*evexP1 |= 0x8;
*evexP2 |= 0x8;
}
}

void setTargetRegisterFieldInEVEX(uint8_t *opcodeByte)
void setTargetRegisterFieldInEVEX(uint8_t *evexP0)
{
uint8_t regNum = ((_fullRegisterBinaryEncodings[_registerNumber].needsRexForByte << 3) | _fullRegisterBinaryEncodings[_registerNumber].id);
uint8_t regNum = ((_fullRegisterBinaryEncodings[_registerNumber].needsRexPlusRXB << 3) | _fullRegisterBinaryEncodings[_registerNumber].id);
uint8_t bits = 0;
*opcodeByte &= 0x6F;
*evexP0 &= 0x6F;

if (regNum & 0x10)
{
Expand All @@ -315,7 +315,7 @@ class OMR_EXTENSIBLE RealRegister : public OMR::X86::RealRegister
bits |= 0x8;
}

*opcodeByte |= (~bits & 0x9) << 4;
*evexP0 |= (~bits & 0x9) << 4;
}

void setRegisterFieldInModRM(uint8_t *modRMByte)
Expand Down
32 changes: 16 additions & 16 deletions compiler/x/i386/codegen/OMRRealRegister.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -216,11 +216,11 @@ class OMR_EXTENSIBLE RealRegister : public OMR::X86::RealRegister
*evex = (*evex & 0xf8) | (0x7 & regNum) | (zero ? 0x80 : 0);
}

void setSourceRegisterFieldInEVEX(uint8_t *opcodeByte)
void setSourceRegisterFieldInEVEX(uint8_t *evexP0)
{
uint8_t regNum = ((_fullRegisterBinaryEncodings[_registerNumber].needsRexForByte << 3) | _fullRegisterBinaryEncodings[_registerNumber].id);
uint8_t regNum = ((_fullRegisterBinaryEncodings[_registerNumber].needsRexPlusRXB << 3) | _fullRegisterBinaryEncodings[_registerNumber].id);
uint8_t bits = 0;
*opcodeByte &= 0x9F;
*evexP0 &= 0x9F;

if (regNum & 0x10)
{
Expand All @@ -232,29 +232,29 @@ class OMR_EXTENSIBLE RealRegister : public OMR::X86::RealRegister
bits |= 0x2;
}

*opcodeByte |= (~bits & 0x6) << 4;
*evexP0 |= (~bits & 0x6) << 4;
}

void setSource2ndRegisterFieldInEVEX(uint8_t *opcodeByte)
void setSource2ndRegisterFieldInEVEX(uint8_t *evexP1)
{
uint8_t regNum = ((_fullRegisterBinaryEncodings[_registerNumber].needsRexForByte << 3) | _fullRegisterBinaryEncodings[_registerNumber].id);
uint8_t regNum = ((_fullRegisterBinaryEncodings[_registerNumber].needsRexPlusRXB << 3) | _fullRegisterBinaryEncodings[_registerNumber].id);

*opcodeByte &= 0x87; // zero out vvvv bits
*opcodeByte |= (~(regNum << 3)) & 0x78;
uint8_t *evexP1 = opcodeByte + 1;
*evexP1 &= 0xf7;
*evexP1 &= 0x87; // zero out vvvv bits
*evexP1 |= (~(regNum << 3)) & 0x78;
uint8_t *evexP2 = evexP1 + 1;
*evexP2 &= 0xf7;

if (!(regNum & 0x10))
{
*evexP1 |= 0x8;
*evexP2 |= 0x8;
}
}

void setTargetRegisterFieldInEVEX(uint8_t *opcodeByte)
void setTargetRegisterFieldInEVEX(uint8_t *evexP0)
{
uint8_t regNum = ((_fullRegisterBinaryEncodings[_registerNumber].needsRexForByte << 3) | _fullRegisterBinaryEncodings[_registerNumber].id);
uint8_t regNum = ((_fullRegisterBinaryEncodings[_registerNumber].needsRexPlusRXB << 3) | _fullRegisterBinaryEncodings[_registerNumber].id);
uint8_t bits = 0;
*opcodeByte &= 0x6F;
*evexP0 &= 0x6F;

if (regNum & 0x10)
{
Expand All @@ -266,7 +266,7 @@ class OMR_EXTENSIBLE RealRegister : public OMR::X86::RealRegister
bits |= 0x8;
}

*opcodeByte |= (~bits & 0x9) << 4;
*evexP0 |= (~bits & 0x9) << 4;
}

/** \brief
Expand All @@ -277,7 +277,7 @@ class OMR_EXTENSIBLE RealRegister : public OMR::X86::RealRegister
*/
void setRegisterFieldInVEX(uint8_t *opcodeByte)
{
*opcodeByte ^= ((_fullRegisterBinaryEncodings[_registerNumber].needsRexForByte << 3) | _fullRegisterBinaryEncodings[_registerNumber].id) << 3; // vvvv is in bits 3-6 of last byte of VEX
*opcodeByte ^= ((_fullRegisterBinaryEncodings[_registerNumber].needsRexPlusRXB << 3) | _fullRegisterBinaryEncodings[_registerNumber].id) << 3; // vvvv is in bits 3-6 of last byte of VEX
}

void setRegisterFieldInModRM(uint8_t *modRMByte)
Expand Down

0 comments on commit 96d6a1d

Please sign in to comment.