Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[X86][MC] Support encoding/decoding for JMPABS #72835

Merged
merged 4 commits into from
Nov 22, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion llvm/include/llvm/Support/X86DisassemblerDecoderCommon.h
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,8 @@ enum attributeBits {
ATTR_EVEXK = 0x1 << 10,
ATTR_EVEXKZ = 0x1 << 11,
ATTR_EVEXB = 0x1 << 12,
ATTR_max = 0x1 << 13,
ATTR_REX2 = 0x1 << 13,
ATTR_max = 0x1 << 14,
};

// Combinations of the above attributes that are relevant to instruction
Expand Down Expand Up @@ -118,6 +119,7 @@ enum attributeBits {
ENUM_ENTRY(IC_64BIT_REXW_OPSIZE, 8, "The Dynamic Duo! Prefer over all " \
"else because this changes most " \
"operands' meaning") \
ENUM_ENTRY(IC_64BIT_REX2, 2, "requires a REX2 prefix") \
ENUM_ENTRY(IC_VEX, 1, "requires a VEX prefix") \
ENUM_ENTRY(IC_VEX_XS, 2, "requires VEX and the XS prefix") \
ENUM_ENTRY(IC_VEX_XD, 2, "requires VEX and the XD prefix") \
Expand Down
5 changes: 5 additions & 0 deletions llvm/lib/Target/X86/Disassembler/X86Disassembler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1257,6 +1257,11 @@ static int getInstructionID(struct InternalInstruction *insn,
attrMask &= ~ATTR_ADSIZE;
}

// Absolute jump need special handling
if (insn->rex2ExtensionPrefix[0] == 0xd5 && insn->opcodeType == ONEBYTE &&
insn->opcode == 0xA1)
attrMask |= ATTR_REX2;

if (insn->mode == MODE_16BIT) {
// JCXZ/JECXZ need special handling for 16-bit mode because the meaning
// of the AdSize prefix is inverted w.r.t. 32-bit mode.
Expand Down
9 changes: 6 additions & 3 deletions llvm/lib/Target/X86/MCTargetDesc/X86BaseInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -966,9 +966,12 @@ namespace X86II {
NoTrackShift = EVEX_RCShift + 1,
NOTRACK = 1ULL << NoTrackShift,

// Force VEX encoding
ExplicitVEXShift = NoTrackShift + 1,
ExplicitVEXPrefix = 1ULL << ExplicitVEXShift
// Force REX2/VEX/EVEX encoding
ExplicitOpPrefixShift = NoTrackShift + 1,
ExplicitREX2Prefix = 1ULL << ExplicitOpPrefixShift,
ExplicitVEXPrefix = 2ULL << ExplicitOpPrefixShift,
ExplicitEVEXPrefix = 3ULL << ExplicitOpPrefixShift,
KanRobert marked this conversation as resolved.
Show resolved Hide resolved
ExplicitOpPrefix = 3ULL << ExplicitOpPrefixShift
};

/// \returns true if the instruction with given opcode is a prefix.
Expand Down
2 changes: 2 additions & 0 deletions llvm/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1305,6 +1305,8 @@ PrefixKind X86MCCodeEmitter::emitREXPrefix(int MemOperand, const MCInst &MI,
}
}
}
if (TSFlags & X86II::ExplicitREX2Prefix)
KanRobert marked this conversation as resolved.
Show resolved Hide resolved
Prefix.setLowerBound(REX2);
switch (TSFlags & X86II::FormMask) {
default:
assert(!HasRegOp && "Unexpected form in emitREXPrefix!");
Expand Down
3 changes: 3 additions & 0 deletions llvm/lib/Target/X86/X86InstrControl.td
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,9 @@ let isBranch = 1, isTerminator = 1, isBarrier = 1, isIndirectBranch = 1 in {
}
}

def JMPABS : Ii64<0xA1, RawFrm, (outs), (ins i64imm:$dst), "jmpabs\t$dst", []>,
KanRobert marked this conversation as resolved.
Show resolved Hide resolved
ExplicitREX2Prefix, Requires<[In64BitMode]>, Sched<[WriteJumpLd]>;

// Loop instructions
let isBranch = 1, isTerminator = 1, SchedRW = [WriteJump] in {
def LOOP : Ii8PCRel<0xE2, RawFrm, (outs), (ins brtarget8:$dst), "loop\t$dst", []>;
Expand Down
18 changes: 14 additions & 4 deletions llvm/lib/Target/X86/X86InstrFormats.td
Original file line number Diff line number Diff line change
Expand Up @@ -271,8 +271,17 @@ class EVEX2VEXOverride<string VEXInstrName> {
// Prevent EVEX->VEX conversion from considering this instruction.
class NotEVEX2VEXConvertible { bit notEVEX2VEXConvertible = 1; }

// Force the instruction to use VEX encoding.
class ExplicitVEXPrefix { bit ExplicitVEXPrefix = 1; }
// Force the instruction to use REX2/VEX/EVEX encoding.
class ExplicitOpPrefix<bits<2> val> {
bits<2> Value = val;
}
def NoExplicitOpPrefix : ExplicitOpPrefix<0>;
def ExplicitREX2 : ExplicitOpPrefix<1>;
def ExplicitVEX : ExplicitOpPrefix<2>;
def ExplicitEVEX : ExplicitOpPrefix<3>;
class ExplicitREX2Prefix { ExplicitOpPrefix explicitOpPrefix = ExplicitREX2; }
class ExplicitVEXPrefix { ExplicitOpPrefix explicitOpPrefix = ExplicitVEX; }
class ExplicitEVEXPrefix { ExplicitOpPrefix explicitOpPrefix = ExplicitEVEX; }

class X86Inst<bits<8> opcod, Format f, ImmType i, dag outs, dag ins,
string AsmStr, Domain d = GenericDomain>
Expand Down Expand Up @@ -354,7 +363,8 @@ class X86Inst<bits<8> opcod, Format f, ImmType i, dag outs, dag ins,
string EVEX2VEXOverride = ?;

bit notEVEX2VEXConvertible = 0; // Prevent EVEX->VEX conversion.
bit ExplicitVEXPrefix = 0; // Force the instruction to use VEX encoding.
ExplicitOpPrefix explicitOpPrefix = NoExplicitOpPrefix;
bits<2> explicitOpPrefixBits = explicitOpPrefix.Value;
Comment on lines +366 to +367
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why need to define both?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We need bits<2> member b/c in X86RecognizableInstr.cpp, byteFromRec requires the bits format.

We need ExplicitOpPrefix member b/c explicitOpPrefix = ExplicitVEX in X86InstrSSE.td.

Similarly, we have both

  OperandSize OpSize = OpSizeFixed; // Does this instruction's encoding change
                                    // based on operand size of the mode?
  bits<2> OpSizeBits = OpSize.Value;
  AddressSize AdSize = AdSizeX; // Does this instruction's encoding change
                                // based on address size of the mode?
  bits<2> AdSizeBits = AdSize.Value;

in this file.

// Force to check predicate before compress EVEX to VEX encoding.
bit checkVEXPredicate = 0;
// TSFlags layout should be kept in sync with X86BaseInfo.h.
Expand All @@ -381,7 +391,7 @@ class X86Inst<bits<8> opcod, Format f, ImmType i, dag outs, dag ins,
let TSFlags{47-45} = !if(!eq(CD8_Scale, 0), 0, !add(!logtwo(CD8_Scale), 1));
let TSFlags{48} = hasEVEX_RC;
let TSFlags{49} = hasNoTrackPrefix;
let TSFlags{50} = ExplicitVEXPrefix;
let TSFlags{51-50} = explicitOpPrefixBits;
}

class PseudoI<dag oops, dag iops, list<dag> pattern>
Expand Down
2 changes: 1 addition & 1 deletion llvm/lib/Target/X86/X86InstrSSE.td
Original file line number Diff line number Diff line change
Expand Up @@ -7316,7 +7316,7 @@ defm VMASKMOVPD : avx_movmask_rm<0x2D, 0x2F, "vmaskmovpd",
// AVX_VNNI
//===----------------------------------------------------------------------===//
let Predicates = [HasAVXVNNI, NoVLX_Or_NoVNNI], Constraints = "$src1 = $dst",
ExplicitVEXPrefix = 1, checkVEXPredicate = 1 in
explicitOpPrefix = ExplicitVEX, checkVEXPredicate = 1 in
multiclass avx_vnni_rm<bits<8> opc, string OpcodeStr, SDNode OpNode,
bit IsCommutable> {
let isCommutable = IsCommutable in
Expand Down
10 changes: 10 additions & 0 deletions llvm/test/MC/Disassembler/X86/apx/jmpabs.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# RUN: llvm-mc -triple x86_64 -disassemble %s | FileCheck %s --check-prefix=ATT
# RUN: llvm-mc -triple x86_64 -disassemble -output-asm-variant=1 %s | FileCheck %s --check-prefix=INTEL

# ATT: jmpabs $1
# INTEL: jmpabs 1
0xd5,0x00,0xa1,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00

# ATT: jmpabs $72623859790382856
# INTEL: jmpabs 72623859790382856
0xd5,0x00,0xa1,0x08,0x07,0x06,0x05,0x04,0x03,0x02,0x01
12 changes: 12 additions & 0 deletions llvm/test/MC/X86/apx/jmpabs-att.s
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# RUN: llvm-mc -triple x86_64 -show-encoding %s | FileCheck %s
# RUN: not llvm-mc -triple i386 -show-encoding %s 2>&1 | FileCheck %s --check-prefix=ERROR

# ERROR-COUNT-2: error:
# ERROR-NOT: error:

# CHECK: jmpabs $1
# CHECK: encoding: [0xd5,0x00,0xa1,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00]
jmpabs $1
# CHECK: jmpabs $72623859790382856
# CHECK: encoding: [0xd5,0x00,0xa1,0x08,0x07,0x06,0x05,0x04,0x03,0x02,0x01]
jmpabs $72623859790382856
8 changes: 8 additions & 0 deletions llvm/test/MC/X86/apx/jmpabs-intel.s
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# RUN: llvm-mc -triple x86_64 -show-encoding -x86-asm-syntax=intel -output-asm-variant=1 %s | FileCheck %s

# CHECK: jmpabs 1
# CHECK: encoding: [0xd5,0x00,0xa1,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00]
jmpabs 1
# CHECK: jmpabs 72623859790382856
# CHECK: encoding: [0xd5,0x00,0xa1,0x08,0x07,0x06,0x05,0x04,0x03,0x02,0x01]
jmpabs 72623859790382856
3 changes: 3 additions & 0 deletions llvm/utils/TableGen/X86DisassemblerTables.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,7 @@ static inline bool inheritsFrom(InstructionContext child,
case IC_64BIT_REXW_XS:
case IC_64BIT_REXW_OPSIZE:
case IC_64BIT_REXW_ADSIZE:
case IC_64BIT_REX2:
return false;
case IC_VEX:
return (VEX_LIG && WIG && inheritsFrom(child, IC_VEX_L_W)) ||
Expand Down Expand Up @@ -908,6 +909,8 @@ void DisassemblerTables::emitContextTable(raw_ostream &o, unsigned &i) const {
o << "_B";
}
}
else if ((index & ATTR_64BIT) && (index & ATTR_REX2))
o << "IC_64BIT_REX2";
else if ((index & ATTR_64BIT) && (index & ATTR_REXW) && (index & ATTR_XS))
o << "IC_64BIT_REXW_XS";
else if ((index & ATTR_64BIT) && (index & ATTR_REXW) && (index & ATTR_XD))
Expand Down
4 changes: 4 additions & 0 deletions llvm/utils/TableGen/X86RecognizableInstr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,8 @@ RecognizableInstrBase::RecognizableInstrBase(const CodeGenInstruction &insn) {
ForceDisassemble = Rec->getValueAsBit("ForceDisassemble");
CD8_Scale = byteFromRec(Rec, "CD8_Scale");
HasVEX_L = Rec->getValueAsBit("hasVEX_L");
ExplicitREX2Prefix =
byteFromRec(Rec, "explicitOpPrefixBits") == X86Local::ExplicitREX2;

EncodeRC = HasEVEX_B &&
(Form == X86Local::MRMDestReg || Form == X86Local::MRMSrcReg);
Expand Down Expand Up @@ -340,6 +342,8 @@ InstructionContext RecognizableInstr::insnContext() const {
insnContext = IC_64BIT_XD;
else if (OpPrefix == X86Local::XS)
insnContext = IC_64BIT_XS;
else if (ExplicitREX2Prefix)
insnContext = IC_64BIT_REX2;
else if (HasREX_W)
insnContext = IC_64BIT_REXW;
else
Expand Down
4 changes: 4 additions & 0 deletions llvm/utils/TableGen/X86RecognizableInstr.h
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,8 @@ namespace X86Local {
enum {
AdSize16 = 1, AdSize32 = 2, AdSize64 = 3
};

enum { ExplicitREX2 = 1 };
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No need enum for one entry.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If no this enum, then in X86RecognizableInstr.cpp, the code would be

  ExplicitREX2Prefix =
      byteFromRec(Rec, "explicitOpPrefixBits") == 1;

which was hard to read.

}

namespace X86Disassembler {
Expand Down Expand Up @@ -206,6 +208,8 @@ struct RecognizableInstrBase {
bool ForceDisassemble;
// The CD8_Scale field from the record
uint8_t CD8_Scale;
/// If explicitOpPrefix field from the record equals ExplicitREX2
bool ExplicitREX2Prefix;
/// \param insn The CodeGenInstruction to extract information from.
RecognizableInstrBase(const CodeGenInstruction &insn);
/// \returns true if this instruction should be emitted
Expand Down
Loading