Skip to content

[X86][MC] Support encoding/decoding for PUSH2[P]/POP2[P] #73233

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

Merged
merged 1 commit into from
Nov 24, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
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
9 changes: 6 additions & 3 deletions llvm/include/llvm/Support/X86DisassemblerDecoderCommon.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ namespace X86Disassembler {
#define XOP9_MAP_SYM x86DisassemblerXOP9Opcodes
#define XOPA_MAP_SYM x86DisassemblerXOPAOpcodes
#define THREEDNOW_MAP_SYM x86Disassembler3DNowOpcodes
#define MAP4_SYM x86DisassemblerMap4Opcodes
#define MAP5_SYM x86DisassemblerMap5Opcodes
#define MAP6_SYM x86DisassemblerMap6Opcodes
#define MAP7_SYM x86DisassemblerMap7Opcodes
Expand All @@ -45,6 +46,7 @@ namespace X86Disassembler {
#define XOP9_MAP_STR "x86DisassemblerXOP9Opcodes"
#define XOPA_MAP_STR "x86DisassemblerXOPAOpcodes"
#define THREEDNOW_MAP_STR "x86Disassembler3DNowOpcodes"
#define MAP4_STR "x86DisassemblerMap4Opcodes"
#define MAP5_STR "x86DisassemblerMap5Opcodes"
#define MAP6_STR "x86DisassemblerMap6Opcodes"
#define MAP7_STR "x86DisassemblerMap7Opcodes"
Expand Down Expand Up @@ -324,9 +326,10 @@ enum OpcodeType {
XOP9_MAP = 5,
XOPA_MAP = 6,
THREEDNOW_MAP = 7,
MAP5 = 8,
MAP6 = 9,
MAP7 = 10
MAP4 = 8,
MAP5 = 9,
MAP6 = 10,
MAP7 = 11
};

// The following structs are used for the hierarchical decode table. After
Expand Down
9 changes: 9 additions & 0 deletions llvm/lib/Target/X86/Disassembler/X86Disassembler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,9 @@ static InstrUID decode(OpcodeType type, InstructionContext insnContext,
dec =
&THREEDNOW_MAP_SYM.opcodeDecisions[insnContext].modRMDecisions[opcode];
break;
case MAP4:
dec = &MAP4_SYM.opcodeDecisions[insnContext].modRMDecisions[opcode];
break;
case MAP5:
dec = &MAP5_SYM.opcodeDecisions[insnContext].modRMDecisions[opcode];
break;
Expand Down Expand Up @@ -929,6 +932,9 @@ static bool readOpcode(struct InternalInstruction *insn) {
case VEX_LOB_0F3A:
insn->opcodeType = THREEBYTE_3A;
return consume(insn, insn->opcode);
case VEX_LOB_MAP4:
insn->opcodeType = MAP4;
return consume(insn, insn->opcode);
case VEX_LOB_MAP5:
insn->opcodeType = MAP5;
return consume(insn, insn->opcode);
Expand Down Expand Up @@ -1100,6 +1106,9 @@ static int getInstructionIDWithAttrMask(uint16_t *instructionID,
case THREEDNOW_MAP:
decision = &THREEDNOW_MAP_SYM;
break;
case MAP4:
decision = &MAP4_SYM;
break;
case MAP5:
decision = &MAP5_SYM;
break;
Expand Down
1 change: 1 addition & 0 deletions llvm/lib/Target/X86/Disassembler/X86DisassemblerDecoder.h
Original file line number Diff line number Diff line change
Expand Up @@ -628,6 +628,7 @@ enum VEXLeadingOpcodeByte {
VEX_LOB_0F = 0x1,
VEX_LOB_0F38 = 0x2,
VEX_LOB_0F3A = 0x3,
VEX_LOB_MAP4 = 0x4,
VEX_LOB_MAP5 = 0x5,
VEX_LOB_MAP6 = 0x6,
VEX_LOB_MAP7 = 0x7
Expand Down
9 changes: 5 additions & 4 deletions llvm/lib/Target/X86/MCTargetDesc/X86BaseInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -757,10 +757,11 @@ enum : uint64_t {
/// we handle this by storeing the classifier in the opcode field and using
/// this flag to indicate that the encoder should do the wacky 3DNow! thing.
ThreeDNow = 7 << OpMapShift,
/// MAP5, MAP6, MAP7 - Prefix after the 0x0F prefix.
T_MAP5 = 8 << OpMapShift,
T_MAP6 = 9 << OpMapShift,
T_MAP7 = 10 << OpMapShift,
/// MAP4, MAP5, MAP6, MAP7 - Prefix after the 0x0F prefix.
T_MAP4 = 8 << OpMapShift,
T_MAP5 = 9 << OpMapShift,
T_MAP6 = 10 << OpMapShift,
T_MAP7 = 11 << OpMapShift,
//===------------------------------------------------------------------===//
/// REX_W - REX prefixes are instruction prefixes used in 64-bit mode.
/// They are used to specify GPRs and SSE registers, 64-bit operand size,
Expand Down
3 changes: 3 additions & 0 deletions llvm/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1013,6 +1013,9 @@ X86MCCodeEmitter::emitVEXOpcodePrefix(int MemOperand, const MCInst &MI,
case X86II::XOPA:
Prefix.set5M(0xA);
break;
case X86II::T_MAP4:
Prefix.set5M(0x4);
break;
case X86II::T_MAP5:
Prefix.set5M(0x5);
break;
Expand Down
12 changes: 9 additions & 3 deletions llvm/lib/Target/X86/X86InstrFormats.td
Original file line number Diff line number Diff line change
Expand Up @@ -161,9 +161,10 @@ def XOP8 : Map<4>;
def XOP9 : Map<5>;
def XOPA : Map<6>;
def ThreeDNow : Map<7>;
def T_MAP5 : Map<8>;
def T_MAP6 : Map<9>;
def T_MAP7 : Map<10>;
def T_MAP4 : Map<8>;
def T_MAP5 : Map<9>;
def T_MAP6 : Map<10>;
def T_MAP7 : Map<11>;

// Class specifying the encoding
class Encoding<bits<2> val> {
Expand Down Expand Up @@ -208,6 +209,11 @@ class XOP8 { Map OpMap = XOP8; Prefix OpPrefix = PS; }
class XOP9 { Map OpMap = XOP9; Prefix OpPrefix = PS; }
class XOPA { Map OpMap = XOPA; Prefix OpPrefix = PS; }
class ThreeDNow { Map OpMap = ThreeDNow; }
class T_MAP4 { Map OpMap = T_MAP4; }
class T_MAP4PS : T_MAP4 { Prefix OpPrefix = PS; } // none
class T_MAP4PD : T_MAP4 { Prefix OpPrefix = PD; } // 0x66
class T_MAP4XS : T_MAP4 { Prefix OpPrefix = XS; } // 0xF3
class T_MAP4XD : T_MAP4 { Prefix OpPrefix = XD; } // 0xF2
class T_MAP5 { Map OpMap = T_MAP5; }
class T_MAP5PS : T_MAP5 { Prefix OpPrefix = PS; } // none
class T_MAP5PD : T_MAP5 { Prefix OpPrefix = PD; } // 0x66
Expand Down
13 changes: 13 additions & 0 deletions llvm/lib/Target/X86/X86InstrMisc.td
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,13 @@ def POP64rmr: I<0x8F, MRM0r, (outs GR64:$reg), (ins), "pop{q}\t$reg", []>,
} // isCodeGenOnly = 1, ForceDisassemble = 1
def POPP64r : I<0x58, AddRegFrm, (outs GR64:$reg), (ins), "popp\t$reg", []>,
REX_W, ExplicitREX2Prefix, Requires<[In64BitMode]>;
def POP2: I<0x8F, MRM0r, (outs GR64:$reg1, GR64:$reg2), (ins),
"pop2\t{$reg2, $reg1|$reg1, $reg2}",
[]>, EVEX_4V, EVEX_B, T_MAP4PS;
def POP2P: I<0x8F, MRM0r, (outs GR64:$reg1, GR64:$reg2), (ins),
"pop2p\t{$reg2, $reg1|$reg1, $reg2}",
[]>, EVEX_4V, EVEX_B, T_MAP4PS, REX_W;

} // 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 @@ -177,6 +184,12 @@ def PUSH64rmr: I<0xFF, MRM6r, (outs), (ins GR64:$reg), "push{q}\t$reg", []>,
} // isCodeGenOnly = 1, ForceDisassemble = 1
def PUSHP64r : I<0x50, AddRegFrm, (outs), (ins GR64:$reg), "pushp\t$reg", []>,
REX_W, ExplicitREX2Prefix, Requires<[In64BitMode]>;
def PUSH2: I<0xFF, MRM6r, (outs), (ins GR64:$reg1, GR64:$reg2),
"push2\t{$reg2, $reg1|$reg1, $reg2}",
[]>, EVEX_4V, EVEX_B, T_MAP4PS;
def PUSH2P: I<0xFF, MRM6r, (outs), (ins GR64:$reg1, GR64:$reg2),
"push2p\t{$reg2, $reg1|$reg1, $reg2}",
[]>, EVEX_4V, EVEX_B, T_MAP4PS, REX_W;
} // 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
58 changes: 58 additions & 0 deletions llvm/test/MC/Disassembler/X86/apx/push2-pop2.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
# 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: push2 %rax, %rdi
# INTEL: push2 rdi, rax
0x62,0xf4,0x44,0x18,0xff,0xf0

# ATT: push2 %rdi, %r8
# INTEL: push2 r8, rdi
0x62,0xf4,0x3c,0x18,0xff,0xf7

# ATT: push2 %r8, %r15
# INTEL: push2 r15, r8
0x62,0xd4,0x04,0x18,0xff,0xf0

# ATT: push2 %r15, %r16
# INTEL: push2 r16, r15
0x62,0xd4,0x7c,0x10,0xff,0xf7

# ATT: push2 %r16, %r23
# INTEL: push2 r23, r16
0x62,0xfc,0x44,0x10,0xff,0xf0

# ATT: push2 %r23, %r24
# INTEL: push2 r24, r23
0x62,0xfc,0x3c,0x10,0xff,0xf7

# ATT: push2 %r24, %r31
# INTEL: push2 r31, r24
0x62,0xdc,0x04,0x10,0xff,0xf0

# ATT: pop2 %rax, %rdi
# INTEL: pop2 rdi, rax
0x62,0xf4,0x44,0x18,0x8f,0xc0

# ATT: pop2 %rdi, %r8
# INTEL: pop2 r8, rdi
0x62,0xf4,0x3c,0x18,0x8f,0xc7

# ATT: pop2 %r8, %r15
# INTEL: pop2 r15, r8
0x62,0xd4,0x04,0x18,0x8f,0xc0

# ATT: pop2 %r15, %r16
# INTEL: pop2 r16, r15
0x62,0xd4,0x7c,0x10,0x8f,0xc7

# ATT: pop2 %r16, %r23
# INTEL: pop2 r23, r16
0x62,0xfc,0x44,0x10,0x8f,0xc0

# ATT: pop2 %r23, %r24
# INTEL: pop2 r24, r23
0x62,0xfc,0x3c,0x10,0x8f,0xc7

# ATT: pop2 %r24, %r31
# INTEL: pop2 r31, r24
0x62,0xdc,0x04,0x10,0x8f,0xc0
58 changes: 58 additions & 0 deletions llvm/test/MC/Disassembler/X86/apx/push2p-pop2p.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
# 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: push2p %rax, %rdi
# INTEL: push2p rdi, rax
0x62,0xf4,0xc4,0x18,0xff,0xf0

# ATT: push2p %rdi, %r8
# INTEL: push2p r8, rdi
0x62,0xf4,0xbc,0x18,0xff,0xf7

# ATT: push2p %r8, %r15
# INTEL: push2p r15, r8
0x62,0xd4,0x84,0x18,0xff,0xf0

# ATT: push2p %r15, %r16
# INTEL: push2p r16, r15
0x62,0xd4,0xfc,0x10,0xff,0xf7

# ATT: push2p %r16, %r23
# INTEL: push2p r23, r16
0x62,0xfc,0xc4,0x10,0xff,0xf0

# ATT: push2p %r23, %r24
# INTEL: push2p r24, r23
0x62,0xfc,0xbc,0x10,0xff,0xf7

# ATT: push2p %r24, %r31
# INTEL: push2p r31, r24
0x62,0xdc,0x84,0x10,0xff,0xf0

# ATT: pop2p %rax, %rdi
# INTEL: pop2p rdi, rax
0x62,0xf4,0xc4,0x18,0x8f,0xc0

# ATT: pop2p %rdi, %r8
# INTEL: pop2p r8, rdi
0x62,0xf4,0xbc,0x18,0x8f,0xc7

# ATT: pop2p %r8, %r15
# INTEL: pop2p r15, r8
0x62,0xd4,0x84,0x18,0x8f,0xc0

# ATT: pop2p %r15, %r16
# INTEL: pop2p r16, r15
0x62,0xd4,0xfc,0x10,0x8f,0xc7

# ATT: pop2p %r16, %r23
# INTEL: pop2p r23, r16
0x62,0xfc,0xc4,0x10,0x8f,0xc0

# ATT: pop2p %r23, %r24
# INTEL: pop2p r24, r23
0x62,0xfc,0xbc,0x10,0x8f,0xc7

# ATT: pop2p %r24, %r31
# INTEL: pop2p r31, r24
0x62,0xdc,0x84,0x10,0x8f,0xc0
45 changes: 45 additions & 0 deletions llvm/test/MC/X86/apx/push2-pop2-att.s
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
# RUN: llvm-mc -triple x86_64 -show-encoding %s | FileCheck %s

# CHECK: push2 %rax, %rdi
# CHECK: encoding: [0x62,0xf4,0x44,0x18,0xff,0xf0]
push2 %rax, %rdi
# CHECK: push2 %rdi, %r8
# CHECK: encoding: [0x62,0xf4,0x3c,0x18,0xff,0xf7]
push2 %rdi, %r8
# CHECK: push2 %r8, %r15
# CHECK: encoding: [0x62,0xd4,0x04,0x18,0xff,0xf0]
push2 %r8, %r15
# CHECK: push2 %r15, %r16
# CHECK: encoding: [0x62,0xd4,0x7c,0x10,0xff,0xf7]
push2 %r15, %r16
# CHECK: push2 %r16, %r23
# CHECK: encoding: [0x62,0xfc,0x44,0x10,0xff,0xf0]
push2 %r16, %r23
# CHECK: push2 %r23, %r24
# CHECK: encoding: [0x62,0xfc,0x3c,0x10,0xff,0xf7]
push2 %r23, %r24
# CHECK: push2 %r24, %r31
# CHECK: encoding: [0x62,0xdc,0x04,0x10,0xff,0xf0]
push2 %r24, %r31

# CHECK: pop2 %rax, %rdi
# CHECK: encoding: [0x62,0xf4,0x44,0x18,0x8f,0xc0]
pop2 %rax, %rdi
# CHECK: pop2 %rdi, %r8
# CHECK: encoding: [0x62,0xf4,0x3c,0x18,0x8f,0xc7]
pop2 %rdi, %r8
# CHECK: pop2 %r8, %r15
# CHECK: encoding: [0x62,0xd4,0x04,0x18,0x8f,0xc0]
pop2 %r8, %r15
# CHECK: pop2 %r15, %r16
# CHECK: encoding: [0x62,0xd4,0x7c,0x10,0x8f,0xc7]
pop2 %r15, %r16
# CHECK: pop2 %r16, %r23
# CHECK: encoding: [0x62,0xfc,0x44,0x10,0x8f,0xc0]
pop2 %r16, %r23
# CHECK: pop2 %r23, %r24
# CHECK: encoding: [0x62,0xfc,0x3c,0x10,0x8f,0xc7]
pop2 %r23, %r24
# CHECK: pop2 %r24, %r31
# CHECK: encoding: [0x62,0xdc,0x04,0x10,0x8f,0xc0]
pop2 %r24, %r31
45 changes: 45 additions & 0 deletions llvm/test/MC/X86/apx/push2-pop2-intel.s
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
# RUN: llvm-mc -triple x86_64 -show-encoding -x86-asm-syntax=intel -output-asm-variant=1 %s | FileCheck %s

# CHECK: push2 rdi, rax
# CHECK: encoding: [0x62,0xf4,0x44,0x18,0xff,0xf0]
push2 rdi, rax
# CHECK: push2 r8, rdi
# CHECK: encoding: [0x62,0xf4,0x3c,0x18,0xff,0xf7]
push2 r8, rdi
# CHECK: push2 r15, r8
# CHECK: encoding: [0x62,0xd4,0x04,0x18,0xff,0xf0]
push2 r15, r8
# CHECK: push2 r16, r15
# CHECK: encoding: [0x62,0xd4,0x7c,0x10,0xff,0xf7]
push2 r16, r15
# CHECK: push2 r23, r16
# CHECK: encoding: [0x62,0xfc,0x44,0x10,0xff,0xf0]
push2 r23, r16
# CHECK: push2 r24, r23
# CHECK: encoding: [0x62,0xfc,0x3c,0x10,0xff,0xf7]
push2 r24, r23
# CHECK: push2 r31, r24
# CHECK: encoding: [0x62,0xdc,0x04,0x10,0xff,0xf0]
push2 r31, r24

# CHECK: pop2 rdi, rax
# CHECK: encoding: [0x62,0xf4,0x44,0x18,0x8f,0xc0]
pop2 rdi, rax
# CHECK: pop2 r8, rdi
# CHECK: encoding: [0x62,0xf4,0x3c,0x18,0x8f,0xc7]
pop2 r8, rdi
# CHECK: pop2 r15, r8
# CHECK: encoding: [0x62,0xd4,0x04,0x18,0x8f,0xc0]
pop2 r15, r8
# CHECK: pop2 r16, r15
# CHECK: encoding: [0x62,0xd4,0x7c,0x10,0x8f,0xc7]
pop2 r16, r15
# CHECK: pop2 r23, r16
# CHECK: encoding: [0x62,0xfc,0x44,0x10,0x8f,0xc0]
pop2 r23, r16
# CHECK: pop2 r24, r23
# CHECK: encoding: [0x62,0xfc,0x3c,0x10,0x8f,0xc7]
pop2 r24, r23
# CHECK: pop2 r31, r24
# CHECK: encoding: [0x62,0xdc,0x04,0x10,0x8f,0xc0]
pop2 r31, r24
Loading