Skip to content

Commit a3cab1f

Browse files
authored
[X86][MC] Support encoding/decoding for PUSHP/POPP (#73092)
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.
1 parent d76d8e5 commit a3cab1f

File tree

5 files changed

+98
-2
lines changed

5 files changed

+98
-2
lines changed

llvm/lib/Target/X86/Disassembler/X86Disassembler.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1257,9 +1257,9 @@ static int getInstructionID(struct InternalInstruction *insn,
12571257
attrMask &= ~ATTR_ADSIZE;
12581258
}
12591259

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

12651265
if (insn->mode == MODE_16BIT) {

llvm/lib/Target/X86/X86InstrMisc.td

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,8 @@ let isCodeGenOnly = 1, ForceDisassemble = 1 in {
161161
def POP64rmr: I<0x8F, MRM0r, (outs GR64:$reg), (ins), "pop{q}\t$reg", []>,
162162
OpSize32, Requires<[In64BitMode]>;
163163
} // isCodeGenOnly = 1, ForceDisassemble = 1
164+
def POPP64r : I<0x58, AddRegFrm, (outs GR64:$reg), (ins), "popp\t$reg", []>,
165+
REX_W, ExplicitREX2Prefix, Requires<[In64BitMode]>;
164166
} // mayLoad, SchedRW
165167
let mayLoad = 1, mayStore = 1, SchedRW = [WriteCopy] in
166168
def POP64rmm: I<0x8F, MRM0m, (outs), (ins i64mem:$dst), "pop{q}\t$dst", []>,
@@ -173,6 +175,8 @@ let isCodeGenOnly = 1, ForceDisassemble = 1 in {
173175
def PUSH64rmr: I<0xFF, MRM6r, (outs), (ins GR64:$reg), "push{q}\t$reg", []>,
174176
OpSize32, Requires<[In64BitMode]>;
175177
} // isCodeGenOnly = 1, ForceDisassemble = 1
178+
def PUSHP64r : I<0x50, AddRegFrm, (outs), (ins GR64:$reg), "pushp\t$reg", []>,
179+
REX_W, ExplicitREX2Prefix, Requires<[In64BitMode]>;
176180
} // mayStore, SchedRW
177181
let mayLoad = 1, mayStore = 1, SchedRW = [WriteCopy] in {
178182
def PUSH64rmm: I<0xFF, MRM6m, (outs), (ins i64mem:$src), "push{q}\t$src", []>,
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
# RUN: llvm-mc -triple x86_64 -disassemble %s | FileCheck %s --check-prefix=ATT
2+
# RUN: llvm-mc -triple x86_64 -disassemble -output-asm-variant=1 %s | FileCheck %s --check-prefix=INTEL
3+
4+
# ATT: pushp %rax
5+
# INTEL: pushp rax
6+
0xd5,0x08,0x50
7+
8+
# ATT: pushp %rbx
9+
# INTEL: pushp rbx
10+
0xd5,0x08,0x53
11+
12+
# ATT: pushp %r15
13+
# INTEL: pushp r15
14+
0xd5,0x09,0x57
15+
16+
# ATT: pushp %r16
17+
# INTEL: pushp r16
18+
0xd5,0x18,0x50
19+
20+
# ATT: popp %rax
21+
# INTEL: popp rax
22+
0xd5,0x08,0x58
23+
24+
# ATT: popp %rbx
25+
# INTEL: popp rbx
26+
0xd5,0x08,0x5b
27+
28+
# ATT: popp %r15
29+
# INTEL: popp r15
30+
0xd5,0x09,0x5f
31+
32+
# ATT: popp %r16
33+
# INTEL: popp r16
34+
0xd5,0x18,0x58

llvm/test/MC/X86/apx/pushp-popp-att.s

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
# RUN: llvm-mc -triple x86_64 -show-encoding %s | FileCheck %s
2+
# RUN: not llvm-mc -triple i386 -show-encoding %s 2>&1 | FileCheck %s --check-prefix=ERROR
3+
4+
# ERROR-COUNT-8: error:
5+
# ERROR-NOT: error:
6+
7+
# CHECK: pushp %rax
8+
# CHECK: encoding: [0xd5,0x08,0x50]
9+
pushp %rax
10+
# CHECK: pushp %rbx
11+
# CHECK: encoding: [0xd5,0x08,0x53]
12+
pushp %rbx
13+
# CHECK: pushp %r15
14+
# CHECK: encoding: [0xd5,0x09,0x57]
15+
pushp %r15
16+
# CHECK: pushp %r16
17+
# CHECK: encoding: [0xd5,0x18,0x50]
18+
pushp %r16
19+
20+
# CHECK: popp %rax
21+
# CHECK: encoding: [0xd5,0x08,0x58]
22+
popp %rax
23+
# CHECK: popp %rbx
24+
# CHECK: encoding: [0xd5,0x08,0x5b]
25+
popp %rbx
26+
# CHECK: popp %r15
27+
# CHECK: encoding: [0xd5,0x09,0x5f]
28+
popp %r15
29+
# CHECK: popp %r16
30+
# CHECK: encoding: [0xd5,0x18,0x58]
31+
popp %r16
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
# RUN: llvm-mc -triple x86_64 -show-encoding -x86-asm-syntax=intel -output-asm-variant=1 %s | FileCheck %s
2+
3+
# CHECK: pushp rax
4+
# CHECK: encoding: [0xd5,0x08,0x50]
5+
pushp rax
6+
# CHECK: pushp rbx
7+
# CHECK: encoding: [0xd5,0x08,0x53]
8+
pushp rbx
9+
# CHECK: pushp r15
10+
# CHECK: encoding: [0xd5,0x09,0x57]
11+
pushp r15
12+
# CHECK: pushp r16
13+
# CHECK: encoding: [0xd5,0x18,0x50]
14+
pushp r16
15+
16+
# CHECK: popp rax
17+
# CHECK: encoding: [0xd5,0x08,0x58]
18+
popp rax
19+
# CHECK: popp rbx
20+
# CHECK: encoding: [0xd5,0x08,0x5b]
21+
popp rbx
22+
# CHECK: popp r15
23+
# CHECK: encoding: [0xd5,0x09,0x5f]
24+
popp r15
25+
# CHECK: popp r16
26+
# CHECK: encoding: [0xd5,0x18,0x58]
27+
popp r16

0 commit comments

Comments
 (0)