Skip to content

Commit

Permalink
[X86][MC] Support encoding/decoding for PUSHP/POPP (#73092)
Browse files Browse the repository at this point in the history
A PUSH and its corresponding POP may be marked with a 1-bit Push-Pop Acceleration (PPX)
hint to indicate that the POP reads the value written by the PUSH from the stack. The PPX hint
is encoded by setting REX2.W = 1 and is applicable only to PUSH with opcode 0x50+rd and POP
with opcode 0x58+rd in the legacy space. It is not applicable to any other variants of PUSH and POP.
  • Loading branch information
KanRobert committed Nov 23, 2023
1 parent d76d8e5 commit a3cab1f
Show file tree
Hide file tree
Showing 5 changed files with 98 additions and 2 deletions.
4 changes: 2 additions & 2 deletions llvm/lib/Target/X86/Disassembler/X86Disassembler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1257,9 +1257,9 @@ static int getInstructionID(struct InternalInstruction *insn,
attrMask &= ~ATTR_ADSIZE;
}

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

if (insn->mode == MODE_16BIT) {
Expand Down
4 changes: 4 additions & 0 deletions llvm/lib/Target/X86/X86InstrMisc.td
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,8 @@ let isCodeGenOnly = 1, ForceDisassemble = 1 in {
def POP64rmr: I<0x8F, MRM0r, (outs GR64:$reg), (ins), "pop{q}\t$reg", []>,
OpSize32, Requires<[In64BitMode]>;
} // isCodeGenOnly = 1, ForceDisassemble = 1
def POPP64r : I<0x58, AddRegFrm, (outs GR64:$reg), (ins), "popp\t$reg", []>,
REX_W, ExplicitREX2Prefix, Requires<[In64BitMode]>;
} // mayLoad, SchedRW
let mayLoad = 1, mayStore = 1, SchedRW = [WriteCopy] in
def POP64rmm: I<0x8F, MRM0m, (outs), (ins i64mem:$dst), "pop{q}\t$dst", []>,
Expand All @@ -173,6 +175,8 @@ let isCodeGenOnly = 1, ForceDisassemble = 1 in {
def PUSH64rmr: I<0xFF, MRM6r, (outs), (ins GR64:$reg), "push{q}\t$reg", []>,
OpSize32, Requires<[In64BitMode]>;
} // isCodeGenOnly = 1, ForceDisassemble = 1
def PUSHP64r : I<0x50, AddRegFrm, (outs), (ins GR64:$reg), "pushp\t$reg", []>,
REX_W, ExplicitREX2Prefix, Requires<[In64BitMode]>;
} // mayStore, SchedRW
let mayLoad = 1, mayStore = 1, SchedRW = [WriteCopy] in {
def PUSH64rmm: I<0xFF, MRM6m, (outs), (ins i64mem:$src), "push{q}\t$src", []>,
Expand Down
34 changes: 34 additions & 0 deletions llvm/test/MC/Disassembler/X86/apx/pushp-popp.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# 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: pushp %rax
# INTEL: pushp rax
0xd5,0x08,0x50

# ATT: pushp %rbx
# INTEL: pushp rbx
0xd5,0x08,0x53

# ATT: pushp %r15
# INTEL: pushp r15
0xd5,0x09,0x57

# ATT: pushp %r16
# INTEL: pushp r16
0xd5,0x18,0x50

# ATT: popp %rax
# INTEL: popp rax
0xd5,0x08,0x58

# ATT: popp %rbx
# INTEL: popp rbx
0xd5,0x08,0x5b

# ATT: popp %r15
# INTEL: popp r15
0xd5,0x09,0x5f

# ATT: popp %r16
# INTEL: popp r16
0xd5,0x18,0x58
31 changes: 31 additions & 0 deletions llvm/test/MC/X86/apx/pushp-popp-att.s
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# 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-8: error:
# ERROR-NOT: error:

# CHECK: pushp %rax
# CHECK: encoding: [0xd5,0x08,0x50]
pushp %rax
# CHECK: pushp %rbx
# CHECK: encoding: [0xd5,0x08,0x53]
pushp %rbx
# CHECK: pushp %r15
# CHECK: encoding: [0xd5,0x09,0x57]
pushp %r15
# CHECK: pushp %r16
# CHECK: encoding: [0xd5,0x18,0x50]
pushp %r16

# CHECK: popp %rax
# CHECK: encoding: [0xd5,0x08,0x58]
popp %rax
# CHECK: popp %rbx
# CHECK: encoding: [0xd5,0x08,0x5b]
popp %rbx
# CHECK: popp %r15
# CHECK: encoding: [0xd5,0x09,0x5f]
popp %r15
# CHECK: popp %r16
# CHECK: encoding: [0xd5,0x18,0x58]
popp %r16
27 changes: 27 additions & 0 deletions llvm/test/MC/X86/apx/pushp-popp-intel.s
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# RUN: llvm-mc -triple x86_64 -show-encoding -x86-asm-syntax=intel -output-asm-variant=1 %s | FileCheck %s

# CHECK: pushp rax
# CHECK: encoding: [0xd5,0x08,0x50]
pushp rax
# CHECK: pushp rbx
# CHECK: encoding: [0xd5,0x08,0x53]
pushp rbx
# CHECK: pushp r15
# CHECK: encoding: [0xd5,0x09,0x57]
pushp r15
# CHECK: pushp r16
# CHECK: encoding: [0xd5,0x18,0x50]
pushp r16

# CHECK: popp rax
# CHECK: encoding: [0xd5,0x08,0x58]
popp rax
# CHECK: popp rbx
# CHECK: encoding: [0xd5,0x08,0x5b]
popp rbx
# CHECK: popp r15
# CHECK: encoding: [0xd5,0x09,0x5f]
popp r15
# CHECK: popp r16
# CHECK: encoding: [0xd5,0x18,0x58]
popp r16

0 comments on commit a3cab1f

Please sign in to comment.