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

Conversation

KanRobert
Copy link
Contributor

@KanRobert KanRobert commented Nov 23, 2023

PUSH2 and POP2 are two new instructions for (respectively) pushing/popping 2 GPRs at a time to/from
the stack. The opcodes of PUSH2 and POP2 are those of “PUSH r/m” and “POP r/m” from legacy map 0, but we
require ModRM.Mod = 3 in order to disallow memory operand.

The 1-bit Push-Pop Acceleration hint described in #73092 applies to PUSH2/POP2 too, then we have PUSH2P/POP2P.

For AT&T syntax, PUSH2[P] pushes the registers from right to left onto the stack. POP2[P] pops the stack to registers from right to left. Intel syntax has the opposite order - from left to right.

The assembly syntax is aligned with GCC & binutils https://gcc.gnu.org/pipermail/gcc-patches/2023-November/637718.html

@llvmbot llvmbot added backend:X86 mc Machine (object) code llvm:support labels Nov 23, 2023
@llvmbot
Copy link
Member

llvmbot commented Nov 23, 2023

@llvm/pr-subscribers-backend-x86
@llvm/pr-subscribers-mc

@llvm/pr-subscribers-llvm-support

Author: Shengchen Kan (KanRobert)

Changes

Patch is 21.04 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/73233.diff

17 Files Affected:

  • (modified) llvm/include/llvm/Support/X86DisassemblerDecoderCommon.h (+6-3)
  • (modified) llvm/lib/Target/X86/Disassembler/X86Disassembler.cpp (+9)
  • (modified) llvm/lib/Target/X86/Disassembler/X86DisassemblerDecoder.h (+1)
  • (modified) llvm/lib/Target/X86/MCTargetDesc/X86BaseInfo.h (+5-4)
  • (modified) llvm/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp (+3)
  • (modified) llvm/lib/Target/X86/X86InstrFormats.td (+9-3)
  • (modified) llvm/lib/Target/X86/X86InstrMisc.td (+13)
  • (added) llvm/test/MC/Disassembler/X86/apx/push2-pop2.txt (+58)
  • (added) llvm/test/MC/Disassembler/X86/apx/push2p-pop2p.txt (+58)
  • (added) llvm/test/MC/X86/apx/push2-pop2-att.s (+45)
  • (added) llvm/test/MC/X86/apx/push2-pop2-intel.s (+45)
  • (added) llvm/test/MC/X86/apx/push2p-pop2p-att.s (+45)
  • (added) llvm/test/MC/X86/apx/push2p-pop2p-intel.s (+45)
  • (modified) llvm/utils/TableGen/X86DisassemblerTables.cpp (+4-3)
  • (modified) llvm/utils/TableGen/X86DisassemblerTables.h (+5-4)
  • (modified) llvm/utils/TableGen/X86RecognizableInstr.cpp (+1)
  • (modified) llvm/utils/TableGen/X86RecognizableInstr.h (+1-1)
diff --git a/llvm/include/llvm/Support/X86DisassemblerDecoderCommon.h b/llvm/include/llvm/Support/X86DisassemblerDecoderCommon.h
index f9089c4755444ab..d75cbfd5fce3fdf 100644
--- a/llvm/include/llvm/Support/X86DisassemblerDecoderCommon.h
+++ b/llvm/include/llvm/Support/X86DisassemblerDecoderCommon.h
@@ -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
@@ -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"
@@ -299,9 +301,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
diff --git a/llvm/lib/Target/X86/Disassembler/X86Disassembler.cpp b/llvm/lib/Target/X86/Disassembler/X86Disassembler.cpp
index d5218d356a5dec8..d50e6514b86d86d 100644
--- a/llvm/lib/Target/X86/Disassembler/X86Disassembler.cpp
+++ b/llvm/lib/Target/X86/Disassembler/X86Disassembler.cpp
@@ -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;
@@ -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);
@@ -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;
diff --git a/llvm/lib/Target/X86/Disassembler/X86DisassemblerDecoder.h b/llvm/lib/Target/X86/Disassembler/X86DisassemblerDecoder.h
index d75f049a6b8d6ff..decc45091941d72 100644
--- a/llvm/lib/Target/X86/Disassembler/X86DisassemblerDecoder.h
+++ b/llvm/lib/Target/X86/Disassembler/X86DisassemblerDecoder.h
@@ -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
diff --git a/llvm/lib/Target/X86/MCTargetDesc/X86BaseInfo.h b/llvm/lib/Target/X86/MCTargetDesc/X86BaseInfo.h
index c1b98d4a4740a5f..26061b4f09b1bde 100644
--- a/llvm/lib/Target/X86/MCTargetDesc/X86BaseInfo.h
+++ b/llvm/lib/Target/X86/MCTargetDesc/X86BaseInfo.h
@@ -829,10 +829,11 @@ namespace X86II {
     /// 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.
diff --git a/llvm/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp b/llvm/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp
index f0fdd593a7fd275..1f130c22298ed47 100644
--- a/llvm/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp
+++ b/llvm/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp
@@ -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;
diff --git a/llvm/lib/Target/X86/X86InstrFormats.td b/llvm/lib/Target/X86/X86InstrFormats.td
index adb6aa12a0628dc..01e14f9848b4ffd 100644
--- a/llvm/lib/Target/X86/X86InstrFormats.td
+++ b/llvm/lib/Target/X86/X86InstrFormats.td
@@ -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> {
@@ -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
diff --git a/llvm/lib/Target/X86/X86InstrMisc.td b/llvm/lib/Target/X86/X86InstrMisc.td
index 9812386f594a29b..32aa82fc93ca302 100644
--- a/llvm/lib/Target/X86/X86InstrMisc.td
+++ b/llvm/lib/Target/X86/X86InstrMisc.td
@@ -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", []>,
@@ -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", []>,
diff --git a/llvm/test/MC/Disassembler/X86/apx/push2-pop2.txt b/llvm/test/MC/Disassembler/X86/apx/push2-pop2.txt
new file mode 100644
index 000000000000000..a9c608119ce379d
--- /dev/null
+++ b/llvm/test/MC/Disassembler/X86/apx/push2-pop2.txt
@@ -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
diff --git a/llvm/test/MC/Disassembler/X86/apx/push2p-pop2p.txt b/llvm/test/MC/Disassembler/X86/apx/push2p-pop2p.txt
new file mode 100644
index 000000000000000..bb22ff8b80e68df
--- /dev/null
+++ b/llvm/test/MC/Disassembler/X86/apx/push2p-pop2p.txt
@@ -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
diff --git a/llvm/test/MC/X86/apx/push2-pop2-att.s b/llvm/test/MC/X86/apx/push2-pop2-att.s
new file mode 100644
index 000000000000000..e1e099e90651863
--- /dev/null
+++ b/llvm/test/MC/X86/apx/push2-pop2-att.s
@@ -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
diff --git a/llvm/test/MC/X86/apx/push2-pop2-intel.s b/llvm/test/MC/X86/apx/push2-pop2-intel.s
new file mode 100644
index 000000000000000..5afb577f2957531
--- /dev/null
+++ b/llvm/test/MC/X86/apx/push2-pop2-intel.s
@@ -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
diff --git a/llvm/test/MC/X86/apx/push2p-pop2p-att.s b/llvm/test/MC/X86/apx/push2p-pop2p-att.s
new file mode 100644
index 000000000000000..36797e1de159796
--- /dev/null
+++ b/llvm/test/MC/X86/apx/push2p-pop2p-att.s
@@ -0,0 +1,45 @@
+# RUN: llvm-mc -triple x86_64 -show-encoding %s | FileCheck %s
+
+# CHECK: push2p	%rax, %rdi
+# CHECK: encoding: [0x62,0xf4,0xc4,0x18,0xff,0xf0]
+         push2p	%rax, %rdi
+# CHECK: push2p	%rdi, %r8
+# CHECK: encoding: [0x62,0xf4,0xbc,0x18,0xff,0xf7]
+         push2p	%rdi, %r8
+# CHECK: push2p	%r8, %r15
+# CHECK: encoding: [0x62,0xd4,0x84,0x18,0xff,0xf0]
+         push2p	%r8, %r15
+# CHECK: push2p	%r15, %r16
+# CHECK: encoding: [0x62,0xd4,0xfc,0x10,0xff,0xf7]
+         push2p	%r15, %r16
+# CHECK: push2p	%r16, %r23
+# CHECK: encoding: [0x62,0xfc,0xc4,0x10,0xff,0xf0]
+         push2p	%r16, %r23
+# CHECK: push2p	%r23, %r24
+# CHECK: encoding: [0x62,0xfc,0xbc,0x10,0xff,0xf7]
+         push2p	%r23, %r24
+# CHECK: push2p	%r24, %r31
+# CHECK: encoding: [0x62,0xdc,0x84,0x10,0xff,0xf0]
+         push2p	%r24, %r31
+
+# CHECK: pop2p	%rax, %rdi
+# CHECK: encoding: [0x62,0xf4,0xc4,0x18,0x8f,0xc0]
+         pop2p	%rax, %rdi
+# CHECK: pop2p	%rdi, %r8
+# CHECK: encoding: [0x62,0xf4,0xbc,0x18,0x8f,0xc7]
+         pop2p	%rdi, %r8
+# CHECK: pop2p	%r8, %r15
+# CHECK: encoding: [0x62,0xd4,0x84,0x18,0x8f,0xc0]
+         pop2p	%r8, %r15
+# CHECK: pop2p	%r15, %r16
+# CHECK: encoding: [0x62,0xd4,0xfc,0x10,0x8f,0xc7]
+         pop2p	%r15, %r16
+# CHECK: pop2p	%r16, %r23
+# CHECK: encoding: [0x62,0xfc,0xc4,0x10,0x8f,0xc0]
+         pop2p	%r16, %r23
+# CHECK: pop2p	%r23, %r24
+# CHECK: encoding: [0x62,0xfc,0xbc,0x10,0x8f,0xc7]
+         pop2p	%r23, %r24
+# CHECK: pop2p	%r24, %r31
+# CHECK: encoding: [0x62,0xdc,0x84,0x10,0x8f,0xc0]
+         pop2p	%r24, %r31
diff --git a/llvm/test/MC/X86/apx/push2p-pop2p-intel.s b/llvm/test/MC/X86/apx/push2p-pop2p-intel.s
new file mode 100644
index 000000000000000..4cefc5c0c93a95a
--- /dev/null
+++ b/llvm/test/MC/X86/apx/push2p-pop2p-intel.s
@@ -0,0 +1,45 @@
+# RUN: llvm-mc -triple x86_64 -show-encoding -x86-asm-syntax=intel -output-asm-variant=1 %s | FileCheck %s
+
+# CHECK: push2p	rdi, rax
+# CHECK: encoding: [0x62,0xf4,0xc4,0x18,0xff,0xf0]
+         push2p	rdi, rax
+# CHECK: push2p	r8, rdi
+# CHECK: encoding: [0x62,0xf4,0xbc,0x18,0xff,0xf7]
+         push2p	r8, rdi
+# CHECK: push2p	r15, r8
+# CHECK: encoding: [0x62,0xd4,0x84,0x18,0xff,0xf0]
+         push2p	r15, r8
+# CHECK: push2p	r16, r15
+# CHECK: encoding: [0x62,0xd4,0xfc,0x10,0xff,0xf7]
+         push2p	r16, r15
+# CHECK: push2p	r23, r16
+# CHECK: encoding: [0x62,0xfc,0xc4,0x10,0xff,0xf0]
+         push2p	r23, r16
+# CHECK: push2p	r24, r23
+# CHECK: encoding: [0x62,0xfc,0xbc,0x10,0xff,0xf7]
+         push2p	r24, r23
+# CHECK: push2p	r31, r24
+# CHECK: encoding: [0x62,0xdc,0x84,0x10,0xff,0xf0]
+         push2p	r31, r24
+
+# CHECK: pop2p	rdi, rax
+# CHECK: encoding: [0x62,0xf4,0xc4,0x18,0x8f,0xc0]
+         pop2p	rdi, rax
+# CHECK: pop2p	r8, rdi
+# CHECK: encoding: [0x62,0xf4,0xbc,0x18,0x8f,0xc7]
+         pop2p	r8, rdi
+# CHECK: pop2p	r15, r8
+# CHECK: encoding: [0x62,0xd4,0x84,0x18,0x8f,0xc0]
+         pop2p	r15, r8
+# CHECK: pop2p	r16, r15
+# CHECK: encoding: [0x62,0xd4,0xfc,0x10,0x8f,0xc7]
+         pop2p	r16, r15
+# CHECK: pop2p	r23, r16
+# CHECK: encoding: [0x62,0xfc,0xc4,0x10,0x8f,0xc0]
+         pop2p	r23, r16
+# CHECK: pop2p	r24, r23
+# CHECK: encoding: [0x62,0xfc,0xbc,0x10,0x8f,0xc7]
+         pop2p	r24, r23
+# CHECK: pop2p	r31, r24
+# CHECK: encoding: [0x62,0xdc,0x84,0x10,0x8f,0xc0]
+         pop2p	r31, r24
diff --git a/llvm/utils/TableGen/X86DisassemblerTables.cpp b/llvm/utils/TableGen/X86DisassemblerTables.cpp
index e8dffaa29c2e041..f879a9f5e4094c5 100644
--- a/llvm/utils/TableGen/X86DisassemblerTables.cpp
+++ b/llvm/utils/TableGen/X86DisassemblerTables.cpp
@@ -983,9 +983,10 @@ void DisassemblerTables::emitContextDecisions(raw_ostream &o1, raw_ostream &o2,
   emitContextDecision(o1, o2, i1, i2, ModRMTableNum, *Tables[5], XOP9_MAP_STR);
   emitContextDecision(o1, o2, i1, i2, ModRMTableNum, *Tables[6], XOPA_MAP_STR);
   emitContextDecision(o1, o2, i1, i2, ModRMTableNum, *Tables[7], THREEDNOW_MAP_STR);
-  emitContextDecision(o1, o2, i1, i2, ModRMTableNum, *Tables[8], MAP5_STR);
-  emitContextDecision(o1, o2, i1, i2, ModRMTableNum, *Tables[9], MAP6_STR);
-  emitContextDecision(o1, o2, i1, i2, ModRMTableNum, *Tables[10], MAP7_STR);
+  emitContextDecision(o1, o2, i1, i2, ModRMTableNum, *Tables[8], MAP4_STR);
+  emitContextDecision(o1, o2, i1, i2, ModRMTableNum, *Tables[9], MAP5_STR);
+  emitContextDecision(o1, o2, i1, i2, ModRMTableNum, *Tables[10], MAP6_STR);
+  emitContextDecision(o1, o2, i1, i2, ModRMTableNum, *Tables[11], MAP7_STR);
 }
 
 void DisassemblerTables::emit(raw_ostream &o) const {
diff --git a/llvm/utils/TableGen/X86DisassemblerTables.h b/llvm/utils/TableGen/X86DisassemblerTables.h
index 4b6f6543acccfca..4fbc58bea3387bb 100644
--- a/llvm/utils/TableGen/X86DisassemblerTables.h
+++ b/llvm/utils/TableGen/X86DisassemblerTables.h
@@ -44,10 +44,11 @@ class DisassemblerTables {
   /// [5] XOP9 map opcode
   /// [6] XOPA map opcode
   /// [7] 3dnow map opcode
-  /// [8] fixed length MAP5 opcode
-  /// [9] fixed length MAP6 opcode
-  /// [10] fixed length MAP7 opcode
-  std::unique_ptr<ContextDecision> Tables[11];
+  /// [8] fixed length MAP4 opcode
+  /// [9] fixed length MAP5 opcode
+  /// [10] fixed length MAP6 opcode
+  /// [11] fixed length MAP7 opcode
+  std::unique_ptr<ContextDecision> Tables[12];
 
   // Table of ModRM encodings.
   typedef std::map<std::vector<unsigned>, unsigned> ModRMMapTy;
diff --git a/llvm/utils/TableGen/X86RecognizableInstr.cpp b/llvm/utils/TableGen/X86RecognizableInstr.cpp
index bcfe7a749c09533..82868c0acff9f50 100644
--- a/llvm/utils/TableGen/X86RecognizableInstr.cpp
+++ b/llvm/utils/Ta...
[truncated]

Copy link

github-actions bot commented Nov 23, 2023

✅ With the latest revision this PR passed the C/C++ code formatter.

Copy link
Contributor

@phoebewang phoebewang left a comment

Choose a reason for hiding this comment

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

LGTM.

@KanRobert KanRobert merged commit 8c2537f into llvm:main Nov 24, 2023
KanRobert added a commit that referenced this pull request Nov 27, 2023
…P/POPP, PUSH2[P]/POP2[P] (#73292)

#73092 supported the encoding/decoding for PUSHP/POPP
#73233 supported the encoding/decoding for PUSH2[P]/POP2[P]

In this patch, we teach frame lowering to spill/reload registers w/
these instructions.

1. Use PPX for balanced spill/reload
2. Use PUSH2/POP2 for continuous spills/reloads
3. PUSH2/POP2 must be 16B-aligned on the stack, so pad when necessary
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants