Skip to content

[PowerPC] Add pnop (prefixed no-op) instruction (ISA v3.1) - #188373

Open
Scottcjn wants to merge 1 commit into
llvm:mainfrom
Scottcjn:ppc-pnop-instruction
Open

[PowerPC] Add pnop (prefixed no-op) instruction (ISA v3.1)#188373
Scottcjn wants to merge 1 commit into
llvm:mainfrom
Scottcjn:ppc-pnop-instruction

Conversation

@Scottcjn

@Scottcjn Scottcjn commented Mar 24, 2026

Copy link
Copy Markdown

Summary

Add the pnop instruction that was missed when prefixed instructions were initially added to the PowerPC backend.

pnop is defined in Power ISA v3.1, Section 3.3.1.2.

Fixes #176831.

Encoding

Field Bits Value
Prefix primary opcode 0-5 1
Prefix type 6-7 3
Prefix remaining 8-31 all zeros
Suffix opcode 32-37 0
Suffix remaining 38-63 all zeros
Prefix word 0x07000000
Suffix word 0x00000000

Like all prefixed instructions, pnop must not cross a 64-byte boundary.

Implementation

  • PNOP in PPCInstrP10.td built on the PI base class, matching how the other prefixed instructions are defined (PI<1, opcode, ...> with the type in bits 6-7)
  • Guarded by the PrefixInstrs predicate
  • No codegen pattern, so it is never selected, but it is left in the disassembler tables so llvm-mc --disassemble can decode it
  • Assembly test: llvm/test/MC/PowerPC/ppc-pnop.s
  • Disassembly test: llvm/test/MC/Disassembler/PowerPC/ppc-pnop.txt

Context

As noted in #176831 by @nemanjai, pnop was intentionally skipped initially since it has no codegen use. @programmerjake is writing a PowerISA decoder and testing against llvm-mc, which needs the disassembler side as well as the assembler side, so both are covered here.

Note: I also have a separate PR (#187322) adding the bctar instruction mentioned in the same discussion thread.

@Scottcjn

Scottcjn commented Apr 7, 2026

Copy link
Copy Markdown
Author

Ping — this adds the pnop (prefixed no-op) instruction from ISA v3.1. Straightforward addition with test coverage. Would appreciate a PowerPC reviewer. cc @nemanjai @stefanp-ibm

@Scottcjn

Scottcjn commented Jul 5, 2026

Copy link
Copy Markdown
Author

Friendly bump on this one. It adds the pnop prefixed no-op (ISA 3.1) and CI is green. @nemanjai @stefanp-ibm if either of you has a moment for a review, it would be appreciated.

pnop is defined in Power ISA v3.1 section 3.3.1.2. The prefix word is
0x07000000 (primary opcode 1, prefix type 3, all other prefix bits zero)
and the suffix word is 0x00000000.

It has no codegen use, so no pattern is attached, but it is left out of
isAsmParserOnly so that the disassembler can decode it as well. That is
the case the original request asked for: checking an external PowerISA
decoder against llvm-mc needs round-trip coverage, not just assembly.

Adds an MC assembly test and an MC disassembly test.
@Scottcjn

Copy link
Copy Markdown
Author

Found and fixed a real encoding bug in this patch, and rebased onto current main (8225c81).

The prefix primary opcode was wrong. PI<7, 0, ...> puts 7 in bits 0-5, which assembles to 0x1c000000, not the 0x07000000 the ISA specifies. Prefixed instructions use primary opcode 1 with the type in bits 6-7, the same as every other PI<1, ...> in PPCInstrP10.td, so this is now PI<1, 0, ...> with Inst{6...7} = 3. The tests were already asserting the correct bytes, so both of them were failing against the old definition.

isAsmParserOnly was also wrong given the goal here. It keeps the instruction out of the disassembler tables, so the disassembly test could never have passed. Dropped it. There is still no pattern attached, so codegen will not select it.

Last, the disassembly test had a little-endian RUN line over the same byte string. The PowerPC disassembler tests feed big-endian instruction bytes from a single run line, so that line is removed.

What I verified, on an x86_64 host with a PowerPC-only Release build (no assertions) at 8225c81: llvm/test/MC/PowerPC and llvm/test/MC/Disassembler/PowerPC pass, apart from ppc32-R_PPC_DTPREL32-reloc.s and ppc64-localentry-symbols.s, which fail identically on unpatched main in this configuration. The PowerPC tblgen backends (subtarget, instr-info, asm-matcher, disassembler, emitter) all run clean. No testing on real Power hardware.

The commit is also re-authored from the noreply address, which may be why premerge has never run on this branch.

@lei137 you have been reviewing my other PowerPC patches, would you be willing to take a look at this one, or point me at the right person?

@llvmorg-github-actions

Copy link
Copy Markdown

@llvm/pr-subscribers-backend-powerpc

Author: AutoJanitor (Scottcjn)

Changes

Summary

Add the pnop instruction that was missed when prefixed instructions were initially added to the PowerPC backend.

pnop is defined in Power ISA v3.1, Section 3.3.1.2.

Fixes #176831.

Encoding

Field Bits Value
Prefix primary opcode 0-5 1
Prefix type 6-7 3
Prefix remaining 8-31 all zeros
Suffix opcode 32-37 0
Suffix remaining 38-63 all zeros
Prefix word 0x07000000
Suffix word 0x00000000

Like all prefixed instructions, pnop must not cross a 64-byte boundary.

Implementation

  • PNOP in PPCInstrP10.td built on the PI base class, matching how the other prefixed instructions are defined (PI&lt;1, opcode, ...&gt; with the type in bits 6-7)
  • Guarded by the PrefixInstrs predicate
  • No codegen pattern, so it is never selected, but it is left in the disassembler tables so llvm-mc --disassemble can decode it
  • Assembly test: llvm/test/MC/PowerPC/ppc-pnop.s
  • Disassembly test: llvm/test/MC/Disassembler/PowerPC/ppc-pnop.txt

Context

As noted in #176831 by @nemanjai, pnop was intentionally skipped initially since it has no codegen use. @programmerjake is writing a PowerISA decoder and testing against llvm-mc, which needs the disassembler side as well as the assembler side, so both are covered here.

Note: I also have a separate PR (#187322) adding the bctar instruction mentioned in the same discussion thread.


Full diff: https://github.com/llvm/llvm-project/pull/188373.diff

3 Files Affected:

  • (modified) llvm/lib/Target/PowerPC/PPCInstrP10.td (+16)
  • (added) llvm/test/MC/Disassembler/PowerPC/ppc-pnop.txt (+6)
  • (added) llvm/test/MC/PowerPC/ppc-pnop.s (+10)
diff --git a/llvm/lib/Target/PowerPC/PPCInstrP10.td b/llvm/lib/Target/PowerPC/PPCInstrP10.td
index 6799a9838ec63..c8c85eb84ad54 100644
--- a/llvm/lib/Target/PowerPC/PPCInstrP10.td
+++ b/llvm/lib/Target/PowerPC/PPCInstrP10.td
@@ -2988,3 +2988,19 @@ let Predicates = [IsISA3_1, PrefixInstrs], isAsmParserOnly = 1, hasNoSchedulingI
                                  (ins s34imm64_pcrel:$SI),
                                  "pla $RT, $SI", IIC_IntSimple, []>, isPCRel;
 }
+
+// pnop - Prefixed No-Op (Power ISA v3.1, Section 3.3.1.2)
+// Prefix word 0x07000000: primary opcode 1, prefix type 3, remaining bits 0.
+// Suffix word 0x00000000. Like all prefixed instructions it must not cross a
+// 64-byte boundary.
+let Predicates = [PrefixInstrs],
+    hasNoSchedulingInfo = 1, hasSideEffects = 0,
+    mayLoad = 0, mayStore = 0 in {
+  def PNOP : PI<1, 0, (outs), (ins), "pnop", IIC_IntSimple> {
+    // Prefix: type 3, remaining prefix bits all zero.
+    let Inst{6...7} = 3;
+    let Inst{8...31} = 0;
+    // Suffix: bits 38-63 all zero (bits 32-37 already = 0 from opcode)
+    let Inst{38...63} = 0;
+  }
+}
diff --git a/llvm/test/MC/Disassembler/PowerPC/ppc-pnop.txt b/llvm/test/MC/Disassembler/PowerPC/ppc-pnop.txt
new file mode 100644
index 0000000000000..eaaef6f0c7e89
--- /dev/null
+++ b/llvm/test/MC/Disassembler/PowerPC/ppc-pnop.txt
@@ -0,0 +1,6 @@
+# RUN: llvm-mc --disassemble %s -triple powerpc64-unknown-linux-gnu \
+# RUN:   -mcpu=pwr10 | FileCheck %s
+
+# Prefixed no-op (Power ISA v3.1). Instruction bytes are big-endian.
+# CHECK: pnop
+0x07 0x00 0x00 0x00 0x00 0x00 0x00 0x00
diff --git a/llvm/test/MC/PowerPC/ppc-pnop.s b/llvm/test/MC/PowerPC/ppc-pnop.s
new file mode 100644
index 0000000000000..39452bd0e9af4
--- /dev/null
+++ b/llvm/test/MC/PowerPC/ppc-pnop.s
@@ -0,0 +1,10 @@
+# RUN: llvm-mc -triple powerpc64-unknown-linux-gnu -show-encoding %s | \
+# RUN:   FileCheck %s --check-prefix=CHECK-BE
+# RUN: llvm-mc -triple powerpc64le-unknown-linux-gnu -show-encoding %s | \
+# RUN:   FileCheck %s --check-prefix=CHECK-LE
+
+# Prefixed no-op (Power ISA v3.1, Section 3.3.1.2)
+# Encoding: prefix 0x0700_0000 + suffix 0x0000_0000
+pnop
+# CHECK-BE: pnop  # encoding: [0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00]
+# CHECK-LE: pnop  # encoding: [0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00]

@laurentketterle-hub

This comment was marked as spam.

1 similar comment
@laurentketterle-hub

This comment was marked as spam.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

powerpc backend is missing pnop instruction definition

3 participants