Blame SOURCES/gdb-rhbz1870031-p10-prefixed-insn-2of3.patch

405ea9
From FEDORA_PATCHES Mon Sep 17 00:00:00 2001
405ea9
From: Keith Seitz <keiths@redhat.com>
405ea9
Date: Thu, 6 May 2021 14:53:00 -0400
405ea9
Subject: gdb-rhbz1870031-p10-prefixed-insn-2of3.patch
405ea9
405ea9
;; Backport "gdb-power10-single-step"
405ea9
;; (Will Schmidt, RHBZ 1870031)
405ea9
405ea9
   commit c8a379440e0f8bf94ed5730e823c9256e64bf37c
405ea9
   Author: Will Schmidt <will_schmidt@vnet.ibm.com>
405ea9
   Date:   Mon Apr 12 14:11:02 2021 -0500
405ea9
405ea9
    [PATCH] gdb-power10-single-step
405ea9
405ea9
    Hi,
405ea9
      This is based on a patch originally written by Alan Modra.
405ea9
    Powerpc / Power10 ISA 3.1 adds prefixed instructions, which
405ea9
    are 8 bytes in length.  This is in contrast to powerpc previously
405ea9
    always having 4 byte instruction length.  This patch implements
405ea9
    changes to allow GDB to better detect prefixed instructions, and
405ea9
    handle single stepping across the 8 byte instructions.
405ea9
405ea9
    Added #defines to help test for PNOP and prefix instructions.
405ea9
    Update ppc_displaced_step_copy_insn() to handle pnop and prefixed
405ea9
    instructions whem R=0 (non-pc-relative).
405ea9
405ea9
    Updated ppc_displaced_step_fixup() to properly handle the offset
405ea9
    value matching the current instruction size
405ea9
405ea9
    Updated the for-loop within ppc_deal_with_atomic_sequence() to
405ea9
    count instructions properly in case we have a mix of 4-byte and
405ea9
    8-byte instructions within the atomic_sequence_length.
405ea9
405ea9
    Added testcase and harness to exercise pc-relative load/store
405ea9
    instructions with R=0.
405ea9
405ea9
    2021-04-12  Will Schmidt  <will_schmidt@vnet.ibm.com>
405ea9
405ea9
            gdb/ChangeLog:
405ea9
            * rs6000-tdep.c:  Add support for single-stepping of
405ea9
            prefixed instructions.
405ea9
405ea9
            gdb/testsuite/ChangeLog:
405ea9
            * gdb.arch/powerpc-plxv-nonrel.s:  Testcase using
405ea9
            non-relative plxv instructions.
405ea9
            * gdb.arch/powerpc-plxv-nonrel.exp: Testcase harness.
405ea9
405ea9
diff --git a/gdb/rs6000-tdep.c b/gdb/rs6000-tdep.c
405ea9
--- a/gdb/rs6000-tdep.c
405ea9
+++ b/gdb/rs6000-tdep.c
405ea9
@@ -814,7 +814,7 @@ typedef BP_MANIPULATION_ENDIAN (little_breakpoint, big_breakpoint)
405ea9
   rs6000_breakpoint;
405ea9
 
405ea9
 /* Instruction masks for displaced stepping.  */
405ea9
-#define BRANCH_MASK 0xfc000000
405ea9
+#define OP_MASK 0xfc000000
405ea9
 #define BP_MASK 0xFC0007FE
405ea9
 #define B_INSN 0x48000000
405ea9
 #define BC_INSN 0x40000000
405ea9
@@ -842,6 +842,11 @@ typedef BP_MANIPULATION_ENDIAN (little_breakpoint, big_breakpoint)
405ea9
 #define ADDPCIS_TARGET_REGISTER 0x03F00000
405ea9
 #define ADDPCIS_INSN_REGSHIFT   21
405ea9
 
405ea9
+#define PNOP_MASK 0xfff3ffff
405ea9
+#define PNOP_INSN 0x07000000
405ea9
+#define R_MASK 0x00100000
405ea9
+#define R_ZERO 0x00000000
405ea9
+
405ea9
 /* Check if insn is one of the Load And Reserve instructions used for atomic
405ea9
    sequences.  */
405ea9
 #define IS_LOAD_AND_RESERVE_INSN(insn)	((insn & LOAD_AND_RESERVE_MASK) == LWARX_INSTRUCTION \
405ea9
@@ -873,10 +878,38 @@ ppc_displaced_step_copy_insn (struct gdbarch *gdbarch,
405ea9
   enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
405ea9
   int insn;
405ea9
 
405ea9
-  read_memory (from, buf, len);
405ea9
+  len = target_read (current_inferior()->top_target(), TARGET_OBJECT_MEMORY, NULL,
405ea9
+		     buf, from, len);
405ea9
+  if ((ssize_t) len < PPC_INSN_SIZE)
405ea9
+    memory_error (TARGET_XFER_E_IO, from);
405ea9
 
405ea9
   insn = extract_signed_integer (buf, PPC_INSN_SIZE, byte_order);
405ea9
 
405ea9
+  /* Check for PNOP and for prefixed instructions with R=0.  Those
405ea9
+     instructions are safe to displace.  Prefixed instructions with R=1
405ea9
+     will read/write data to/from locations relative to the current PC.
405ea9
+     We would not be able to fixup after an instruction has written data
405ea9
+    into a displaced location, so decline to displace those instructions.  */
405ea9
+  if ((insn & OP_MASK) == 1 << 26)
405ea9
+    {
405ea9
+      if (((insn & PNOP_MASK) != PNOP_INSN)
405ea9
+	  && ((insn & R_MASK) != R_ZERO))
405ea9
+	{
405ea9
+	  fprintf_unfiltered (gdb_stdlog,
405ea9
+			      "displaced: {ppc} Not displacing prefixed "
405ea9
+			      "instruction %08x at %s",
405ea9
+			      insn, paddress (gdbarch, from));
405ea9
+	  return NULL;
405ea9
+	}
405ea9
+    }
405ea9
+  else
405ea9
+    /* Non-prefixed instructions..  */
405ea9
+    {
405ea9
+      /* Set the instruction length to 4 to match the actual instruction
405ea9
+	 length.  */
405ea9
+      len = 4;
405ea9
+    }
405ea9
+
405ea9
   /* Assume all atomic sequences start with a Load and Reserve instruction.  */
405ea9
   if (IS_LOAD_AND_RESERVE_INSN (insn))
405ea9
     {
405ea9
@@ -917,11 +950,17 @@ ppc_displaced_step_fixup (struct gdbarch *gdbarch,
405ea9
   ppc_displaced_step_closure *closure = (ppc_displaced_step_closure *) closure_;
405ea9
   ULONGEST insn  = extract_unsigned_integer (closure->buf.data (),
405ea9
 					     PPC_INSN_SIZE, byte_order);
405ea9
-  ULONGEST opcode = 0;
405ea9
+  ULONGEST opcode;
405ea9
   /* Offset for non PC-relative instructions.  */
405ea9
-  LONGEST offset = PPC_INSN_SIZE;
405ea9
+  LONGEST offset;
405ea9
 
405ea9
-  opcode = insn & BRANCH_MASK;
405ea9
+  opcode = insn & OP_MASK;
405ea9
+
405ea9
+  /* Set offset to 8 if this is an 8-byte (prefixed) instruction.  */
405ea9
+  if ((opcode) == 1 << 26)
405ea9
+    offset = 2 * PPC_INSN_SIZE;
405ea9
+  else
405ea9
+    offset = PPC_INSN_SIZE;
405ea9
 
405ea9
   if (debug_displaced)
405ea9
     fprintf_unfiltered (gdb_stdlog,
405ea9
@@ -1058,13 +1097,16 @@ ppc_deal_with_atomic_sequence (struct regcache *regcache)
405ea9
      instructions.  */
405ea9
   for (insn_count = 0; insn_count < atomic_sequence_length; ++insn_count)
405ea9
     {
405ea9
-      loc += PPC_INSN_SIZE;
405ea9
+      if ((insn & OP_MASK) == 1 << 26)
405ea9
+       loc += 2 * PPC_INSN_SIZE;
405ea9
+      else
405ea9
+       loc += PPC_INSN_SIZE;
405ea9
       insn = read_memory_integer (loc, PPC_INSN_SIZE, byte_order);
405ea9
 
405ea9
       /* Assume that there is at most one conditional branch in the atomic
405ea9
          sequence.  If a conditional branch is found, put a breakpoint in 
405ea9
          its destination address.  */
405ea9
-      if ((insn & BRANCH_MASK) == BC_INSN)
405ea9
+      if ((insn & OP_MASK) == BC_INSN)
405ea9
         {
405ea9
           int immediate = ((insn & 0xfffc) ^ 0x8000) - 0x8000;
405ea9
           int absolute = insn & 2;
405ea9
@@ -7095,7 +7137,7 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
405ea9
   set_gdbarch_displaced_step_location (gdbarch,
405ea9
 				       displaced_step_at_entry_point);
405ea9
 
405ea9
-  set_gdbarch_max_insn_length (gdbarch, PPC_INSN_SIZE);
405ea9
+  set_gdbarch_max_insn_length (gdbarch, 2 * PPC_INSN_SIZE);
405ea9
 
405ea9
   /* Hook in ABI-specific overrides, if they have been registered.  */
405ea9
   info.target_desc = tdesc;
405ea9
diff --git a/gdb/testsuite/gdb.arch/powerpc-addpcis.exp b/gdb/testsuite/gdb.arch/powerpc-addpcis.exp
405ea9
new file mode 100644
405ea9
--- /dev/null
405ea9
+++ b/gdb/testsuite/gdb.arch/powerpc-addpcis.exp
405ea9
@@ -0,0 +1,104 @@
405ea9
+# Copyright 2021 Free Software Foundation, Inc.
405ea9
+
405ea9
+# This program is free software; you can redistribute it and/or modify
405ea9
+# it under the terms of the GNU General Public License as published by
405ea9
+# the Free Software Foundation; either version 3 of the License, or
405ea9
+# (at your option) any later version.
405ea9
+#
405ea9
+# This program is distributed in the hope that it will be useful,
405ea9
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
405ea9
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
405ea9
+# GNU General Public License for more details.
405ea9
+#
405ea9
+# You should have received a copy of the GNU General Public License
405ea9
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
405ea9
+
405ea9
+
405ea9
+# Test to confirm that gdb is properly single stepping over the
405ea9
+# displaced addpcis instruction.
405ea9
+# The addpcis instruction and its extended mnemonics lnia and subpcis
405ea9
+# apply an immediate shifted value (X || 0x0000) to the current PC/NIA
405ea9
+# value, and store that value into the instructions target register.
405ea9
+# When the instruction is displaced, it needs special handling.
405ea9
+
405ea9
+# lnia Rx == addpcis Rx,0
405ea9
+# subcis Rx,value == addpcis Rx,-value
405ea9
+
405ea9
+if { ![istarget powerpc*-*] } {
405ea9
+    verbose "Skipping powerpc addpcis test."
405ea9
+    return
405ea9
+}
405ea9
+
405ea9
+set retval 0
405ea9
+
405ea9
+standard_testfile .s
405ea9
+
405ea9
+if { [prepare_for_testing "failed to prepare" $testfile "$srcfile" \
405ea9
+      {debug quiet}] } {
405ea9
+    return -1
405ea9
+}
405ea9
+
405ea9
+if ![runto_main] then {
405ea9
+      return
405ea9
+}
405ea9
+
405ea9
+set check_pc [get_hexadecimal_valueof "\$pc" "default0"]
405ea9
+set bp1 *$check_pc+4
405ea9
+set bp2 *$check_pc+12
405ea9
+set bp3 *$check_pc+16
405ea9
+gdb_breakpoint $bp1
405ea9
+gdb_breakpoint $bp2
405ea9
+gdb_breakpoint $bp3
405ea9
+
405ea9
+gdb_test "stepi" "" "set r3 "
405ea9
+set check_r3 [get_hexadecimal_valueof "\$r3" "default0"]
405ea9
+gdb_test "stepi" "" "set r4"
405ea9
+set check_r4 [get_hexadecimal_valueof "\$r4" "default0"]
405ea9
+gdb_test "stepi" "" "set r5"
405ea9
+set check_r5 [get_hexadecimal_valueof "\$r5" "default0"]
405ea9
+gdb_test "stepi" "" "set r6"
405ea9
+set check_r6 [get_hexadecimal_valueof "\$r6" "default0"]
405ea9
+gdb_test "stepi" "" "set r7"
405ea9
+set check_r7 [get_hexadecimal_valueof "\$r7" "default0"]
405ea9
+gdb_test "stepi" "" "set r8"
405ea9
+set check_r8 [get_hexadecimal_valueof "\$r8" "default0"]
405ea9
+gdb_test "stepi" "" "set r9"
405ea9
+set check_r9 [get_hexadecimal_valueof "\$r9" "default0"]
405ea9
+
405ea9
+# R6 will contain the reference value.  All other
405ea9
+# instructions in this test will be storing values
405ea9
+# relative to what is stored in R6.
405ea9
+
405ea9
+#	subpcis 3,+0x100 	# /* set r3 */
405ea9
+#	subpcis 4,+0x10		# /* set r4 */
405ea9
+#	subpcis 5,+0x1		# /* set r5 */
405ea9
+#	lnia    6		# /* set r6 */
405ea9
+#	addpcis 7,+0x1		# /* set r7 */
405ea9
+#	addpcis 8,+0x10		# /* set r8 */
405ea9
+#	addpcis 9,+0x100	# /* set r9 */
405ea9
+
405ea9
+if [expr $check_r3 + 0x1000000   != $check_r6 - 0xc ] {
405ea9
+    fail "unexpected value r3 + 0x1,000,000 != r6 + 0xc ; r3: $check_r3  r6: $check_r6 "
405ea9
+}
405ea9
+if [expr $check_r4 + 0x100000  != $check_r6 - 0x8 ] {
405ea9
+    fail "unexpected value r4 + 0x100,000 != r6 - 0x8 ; r4: $check_r4  r6: $check_r6 "
405ea9
+}
405ea9
+if [expr $check_r5 + 0x10000  != $check_r6 - 0x4 ] {
405ea9
+    fail "unexpected value r5 + 0x10,000 != r6 , r5: $check_r5  r6: $check_r6 "
405ea9
+}
405ea9
+if [expr $check_r6 != $check_r6] {
405ea9
+    fail "unexpected value r6 != r6 , r6: $check_r6  r6: $check_r6 "
405ea9
+}
405ea9
+if [expr $check_r7 - 0x10000  != $check_r6 + 0x4] {
405ea9
+    fail "unexpected value r7 - 0x10,000 != r6 + 0x4 , r7: $check_r7  r7: $check_r6 "
405ea9
+}
405ea9
+if [expr $check_r8 - 0x100000  != $check_r6 + 0x8 ] {
405ea9
+    fail "unexpected value r8 - 0x100,000 != r6 , r8: $check_r8  r8: $check_r6 "
405ea9
+}
405ea9
+if [expr $check_r9 - 0x1000000  != $check_r6 + 0xc ] {
405ea9
+    fail "unexpected value r9 - 0x1,000,000 != r6 + 0xc , r9: $check_r9  r6: $check_r6 "
405ea9
+}
405ea9
+
405ea9
+gdb_test "info break"
405ea9
+gdb_test "info register r3 r4 r5 r6 r7 r8 r9"
405ea9
+gdb_test "disas main"
405ea9
diff --git a/gdb/testsuite/gdb.arch/powerpc-addpcis.s b/gdb/testsuite/gdb.arch/powerpc-addpcis.s
405ea9
new file mode 100644
405ea9
--- /dev/null
405ea9
+++ b/gdb/testsuite/gdb.arch/powerpc-addpcis.s
405ea9
@@ -0,0 +1,33 @@
405ea9
+/* This testcase is part of GDB, the GNU debugger.
405ea9
+
405ea9
+   Copyright 2021 Free Software Foundation, Inc.
405ea9
+
405ea9
+   This program is free software; you can redistribute it and/or modify
405ea9
+   it under the terms of the GNU General Public License as published by
405ea9
+   the Free Software Foundation; either version 3 of the License, or
405ea9
+   (at your option) any later version.
405ea9
+
405ea9
+   This program is distributed in the hope that it will be useful,
405ea9
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
405ea9
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
405ea9
+   GNU General Public License for more details.
405ea9
+
405ea9
+   You should have received a copy of the GNU General Public License
405ea9
+   along with this program.  If not, see <http://www.gnu.org/licenses/>. */
405ea9
+
405ea9
+
405ea9
+/*  Test to confirm that gdb is properly single stepping over the
405ea9
+    displaced addpcis instruction.  */
405ea9
+
405ea9
+.global main
405ea9
+.type main,function
405ea9
+# addpcis: the sum of NIA + ( D || 0x0000) is placed in RT.
405ea9
+main:
405ea9
+	subpcis 3,+0x100  	# /* set r3 */
405ea9
+	subpcis 4,+0x10  	# /* set r4 */
405ea9
+	subpcis 5,+0x1  	# /* set r5 */
405ea9
+	lnia    6  		# /* set r6 */
405ea9
+	addpcis 7,+0x1  	# /* set r7 */
405ea9
+	addpcis 8,+0x10  	# /* set r8 */
405ea9
+	addpcis 9,+0x100  	# /* set r9 */
405ea9
+	blr
405ea9
diff --git a/gdb/testsuite/gdb.arch/powerpc-lnia.exp b/gdb/testsuite/gdb.arch/powerpc-lnia.exp
405ea9
new file mode 100644
405ea9
--- /dev/null
405ea9
+++ b/gdb/testsuite/gdb.arch/powerpc-lnia.exp
405ea9
@@ -0,0 +1,100 @@
405ea9
+# Copyright 2021 Free Software Foundation, Inc.
405ea9
+
405ea9
+# This program is free software; you can redistribute it and/or modify
405ea9
+# it under the terms of the GNU General Public License as published by
405ea9
+# the Free Software Foundation; either version 3 of the License, or
405ea9
+# (at your option) any later version.
405ea9
+#
405ea9
+# This program is distributed in the hope that it will be useful,
405ea9
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
405ea9
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
405ea9
+# GNU General Public License for more details.
405ea9
+#
405ea9
+# You should have received a copy of the GNU General Public License
405ea9
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
405ea9
+
405ea9
+# Test to see if gdb is properly single stepping over the
405ea9
+# displaced lnia instruction.  This test checks that a series
405ea9
+# of lnia instructions are loading ascending values as expected.
405ea9
+
405ea9
+# lnia is an extended mnemonic for the addpcis instruction, which
405ea9
+# stores the $NIA plus an immediate value into a register.
405ea9
+#
405ea9
+#		lnia Rx == addpcis Rx,0 == lnia Rx
405ea9
+#		subcis Rx,value == addpcis Rx,-value
405ea9
+
405ea9
+if { ![istarget powerpc*-*] } {
405ea9
+    verbose "Skipping powerpc lnia test."
405ea9
+    return
405ea9
+}
405ea9
+
405ea9
+set retval 0
405ea9
+
405ea9
+standard_testfile .s
405ea9
+
405ea9
+if { [prepare_for_testing "failed to prepare" $testfile "$srcfile" \
405ea9
+      {debug quiet}] } {
405ea9
+    return -1
405ea9
+}
405ea9
+
405ea9
+if ![runto_main] then {
405ea9
+      return
405ea9
+}
405ea9
+
405ea9
+set before_pc 0
405ea9
+set check_pc [get_hexadecimal_valueof "\$pc" "default0"]
405ea9
+
405ea9
+# set some breakpoints on the instructions below main().
405ea9
+set bp1 *$check_pc+4
405ea9
+set bp2 *$check_pc+12
405ea9
+set bp3 *$check_pc+16
405ea9
+gdb_breakpoint $bp1
405ea9
+gdb_breakpoint $bp2
405ea9
+gdb_breakpoint $bp3
405ea9
+
405ea9
+# single-step through the lnia instructions, and retrieve the
405ea9
+# register values as we proceed.
405ea9
+gdb_test "stepi" "" "set r3"
405ea9
+set check_r3 [get_hexadecimal_valueof "\$r3" "default0"]
405ea9
+gdb_test "stepi" "" "set r4"
405ea9
+set check_r4 [get_hexadecimal_valueof "\$r4" "default0"]
405ea9
+gdb_test "stepi" "" "set r5"
405ea9
+set check_r5 [get_hexadecimal_valueof "\$r5" "default0"]
405ea9
+gdb_test "stepi" "" "set r6"
405ea9
+set check_r6 [get_hexadecimal_valueof "\$r6" "default0"]
405ea9
+gdb_test "stepi" "" "set r7"
405ea9
+set check_r7 [get_hexadecimal_valueof "\$r7" "default0"]
405ea9
+gdb_test "stepi" "" "set r8"
405ea9
+set check_r8 [get_hexadecimal_valueof "\$r8" "default0"]
405ea9
+gdb_test "stepi" "" "set r9"
405ea9
+set check_r9 [get_hexadecimal_valueof "\$r9" "default0"]
405ea9
+
405ea9
+# Ensure that our register values are as expected.
405ea9
+# Specifically that the values loaded by the lnia instruction
405ea9
+# reflect the value of the PC as if the instruction was
405ea9
+# not displaced.
405ea9
+if [expr $check_r3 + 4 != $check_r4] {
405ea9
+    fail "unexpected value r3+4 != r4 , r3: $check_r3  r4: $check_r4 "
405ea9
+}
405ea9
+if [expr $check_r4 + 4 != $check_r5] {
405ea9
+    fail "unexpected value r4+4 != r5 , r4: $check_r4  r5: $check_r5 "
405ea9
+}
405ea9
+if [expr $check_r5 + 4 != $check_r6] {
405ea9
+    fail "unexpected value r5+4 != r6 , r5: $check_r5  r6: $check_r6 "
405ea9
+}
405ea9
+if [expr $check_r6 + 4 != $check_r7] {
405ea9
+    fail "unexpected value r6+4 != r7 , r6: $check_r6  r7: $check_r7 "
405ea9
+}
405ea9
+if [expr $check_r7 + 4 != $check_r8] {
405ea9
+    fail "unexpected value r7+4 != r8 , r7: $check_r7  r8: $check_r8 "
405ea9
+}
405ea9
+if [expr $check_r8 + 4 != $check_r9] {
405ea9
+    fail "unexpected value r8+4 != r9 , r8: $check_r8  r9: $check_r9 "
405ea9
+}
405ea9
+
405ea9
+gdb_test "info break"
405ea9
+gdb_test "info register r3 r4 r5 r6 r7 r8 r9"
405ea9
+gdb_test "disas main"
405ea9
+
405ea9
+# Let the inferior store all vector registers in a buffer, then dump
405ea9
+# the buffer and check it.
405ea9
diff --git a/gdb/testsuite/gdb.arch/powerpc-lnia.s b/gdb/testsuite/gdb.arch/powerpc-lnia.s
405ea9
new file mode 100644
405ea9
--- /dev/null
405ea9
+++ b/gdb/testsuite/gdb.arch/powerpc-lnia.s
405ea9
@@ -0,0 +1,32 @@
405ea9
+/* This testcase is part of GDB, the GNU debugger.
405ea9
+
405ea9
+   Copyright 2021 Free Software Foundation, Inc.
405ea9
+
405ea9
+   This program is free software; you can redistribute it and/or modify
405ea9
+   it under the terms of the GNU General Public License as published by
405ea9
+   the Free Software Foundation; either version 3 of the License, or
405ea9
+   (at your option) any later version.
405ea9
+
405ea9
+   This program is distributed in the hope that it will be useful,
405ea9
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
405ea9
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
405ea9
+   GNU General Public License for more details.
405ea9
+
405ea9
+   You should have received a copy of the GNU General Public License
405ea9
+   along with this program.  If not, see <http://www.gnu.org/licenses/>. */
405ea9
+
405ea9
+/* Test to confirm that gdb properly handles lnia instructions
405ea9
+   that load the current PC into a target register when executed
405ea9
+   from a displaced location.  */
405ea9
+
405ea9
+.global main
405ea9
+.type main,function
405ea9
+main:
405ea9
+	lnia 3  # /* set r3 */
405ea9
+	lnia 4  # /* set r4 */
405ea9
+	lnia 5  # /* set r5 */
405ea9
+	lnia 6  # /* set r6 */
405ea9
+	lnia 7  # /* set r7 */
405ea9
+	lnia 8  # /* set r8 */
405ea9
+	lnia 9  # /* set r9 */
405ea9
+	blr
405ea9
diff --git a/gdb/testsuite/gdb.arch/powerpc-plxv-nonrel.exp b/gdb/testsuite/gdb.arch/powerpc-plxv-nonrel.exp
405ea9
new file mode 100644
405ea9
--- /dev/null
405ea9
+++ b/gdb/testsuite/gdb.arch/powerpc-plxv-nonrel.exp
405ea9
@@ -0,0 +1,130 @@
405ea9
+# Copyright 2021 Free Software Foundation, Inc.
405ea9
+
405ea9
+# This program is free software; you can redistribute it and/or modify
405ea9
+# it under the terms of the GNU General Public License as published by
405ea9
+# the Free Software Foundation; either version 3 of the License, or
405ea9
+# (at your option) any later version.
405ea9
+#
405ea9
+# This program is distributed in the hope that it will be useful,
405ea9
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
405ea9
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
405ea9
+# GNU General Public License for more details.
405ea9
+#
405ea9
+# You should have received a copy of the GNU General Public License
405ea9
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
405ea9
+
405ea9
+# Test to see if gdb is properly single stepping over the
405ea9
+# displaced plxv instruction.
405ea9
+
405ea9
+if { ![istarget powerpc*-*] } {
405ea9
+    verbose "Skipping powerpc plxv test."
405ea9
+    return
405ea9
+}
405ea9
+
405ea9
+set retval 0
405ea9
+
405ea9
+standard_testfile .s
405ea9
+
405ea9
+if { [prepare_for_testing "failed to prepare" $testfile "$srcfile" \
405ea9
+      {debug quiet}] } {
405ea9
+    return -1
405ea9
+}
405ea9
+
405ea9
+gdb_test "set radix 0b10000"
405ea9
+gdb_test "set debug displaced"
405ea9
+
405ea9
+if ![runto_main] then {
405ea9
+      return
405ea9
+}
405ea9
+
405ea9
+gdb_test "set debug displaced on"
405ea9
+
405ea9
+# Proc to extract the uint128 hex value from the output of
405ea9
+# a print vector statement.
405ea9
+proc get_vector_hexadecimal_valueof { exp default {test ""} } {
405ea9
+	set val "0x0000"
405ea9
+	global gdb_prompt
405ea9
+	if {$test == ""} {
405ea9
+		set test "get vector_hexadecimal valueof \"${exp}\""
405ea9
+	}
405ea9
+	gdb_test_multiple "print $${exp}.uint128" $test {
405ea9
+		-re -wrap "\\$\[0-9\]* = (0x\[0-9a-zA-Z\]+).*" {
405ea9
+			set val $expect_out(1,string)
405ea9
+				pass "$test"
405ea9
+		}
405ea9
+		-re -wrap ".*Illegal instruction.* $" {
405ea9
+			fail "Illegal instruction on print."
405ea9
+			set val 0xffff
405ea9
+		}
405ea9
+	}
405ea9
+	return ${val}
405ea9
+}
405ea9
+
405ea9
+# Proc to do a single-step, and ensure we gently handle
405ea9
+# an illegal instruction situation.
405ea9
+proc stepi_over_instruction { xyz } {
405ea9
+	global gdb_prompt
405ea9
+	gdb_test_multiple "stepi" "${xyz} " {
405ea9
+		-re -wrap ".*Illegal instruction.*" {
405ea9
+			fail "Illegal instruction on single step."
405ea9
+		return
405ea9
+		}
405ea9
+		-re -wrap ".*" {
405ea9
+		 pass "stepi ${xyz}"
405ea9
+		}
405ea9
+	}
405ea9
+}
405ea9
+
405ea9
+set check_pc [get_hexadecimal_valueof "\$pc" "default0"]
405ea9
+
405ea9
+# set some breakpoints on the instructions below main().
405ea9
+gdb_test "disas /r main"
405ea9
+set bp1 *$check_pc+4
405ea9
+set bp2 *$check_pc+0d12
405ea9
+set bp3 *$check_pc+0d20
405ea9
+set bp4 *$check_pc+0d28
405ea9
+gdb_breakpoint $bp1
405ea9
+gdb_breakpoint $bp2
405ea9
+gdb_breakpoint $bp3
405ea9
+gdb_breakpoint $bp4
405ea9
+
405ea9
+# single-step through the plxv instructions, and retrieve the
405ea9
+# register values as we proceed.
405ea9
+
405ea9
+stepi_over_instruction  "stepi over NOP"
405ea9
+stepi_over_instruction  "stepi over lnia"
405ea9
+stepi_over_instruction  "stepi over addi"
405ea9
+
405ea9
+stepi_over_instruction  "stepi over vs4 assignment"
405ea9
+set check_vs4 [get_vector_hexadecimal_valueof "vs4" "default0"]
405ea9
+
405ea9
+stepi_over_instruction  "stepi over vs5 assignment"
405ea9
+set check_vs5 [get_vector_hexadecimal_valueof "vs5" "default0"]
405ea9
+
405ea9
+stepi_over_instruction  "stepi over vs6 assignment"
405ea9
+set check_vs6 [get_vector_hexadecimal_valueof "vs6" "default0"]
405ea9
+
405ea9
+stepi_over_instruction  "stepi over vs7 assignment"
405ea9
+set check_vs7 [get_vector_hexadecimal_valueof "vs7" "default0"]
405ea9
+
405ea9
+set vs4_expected 0xa5b5c5d5a4b4c4d4a3b3c3d3a2b2c2d2
405ea9
+set vs5_expected 0xa7b7c7d7a6b6c6d6a5b5c5d5a4b4c4d4
405ea9
+set vs6_expected 0xa9b9c9d9a8b8c8d8a7b7c7d7a6b6c6d6
405ea9
+set vs7_expected 0xabbbcbdbaabacadaa9b9c9d9a8b8c8d8
405ea9
+
405ea9
+if [expr  $check_vs4 != $vs4_expected] {
405ea9
+    fail "unexpected value vs4;  actual:$check_vs4 expected:$vs4_expected"
405ea9
+}
405ea9
+if [expr $check_vs5 != $vs5_expected ] {
405ea9
+    fail "unexpected value vs5;   actual:$check_vs5 expected:$vs5_expected"
405ea9
+}
405ea9
+if [expr $check_vs6 != $vs6_expected ] {
405ea9
+    fail "unexpected value vs6;   actual:$check_vs6 expected:$vs6_expected"
405ea9
+}
405ea9
+if [expr $check_vs7 != $vs7_expected ] {
405ea9
+    fail "unexpected value vs7;   actual:$check_vs7 expected:$vs7_expected"
405ea9
+}
405ea9
+
405ea9
+gdb_test "info break"
405ea9
+gdb_test "info register vs4 vs5 vs6 vs7 "
405ea9
+gdb_test "disas main #2"
405ea9
diff --git a/gdb/testsuite/gdb.arch/powerpc-plxv-nonrel.s b/gdb/testsuite/gdb.arch/powerpc-plxv-nonrel.s
405ea9
new file mode 100644
405ea9
--- /dev/null
405ea9
+++ b/gdb/testsuite/gdb.arch/powerpc-plxv-nonrel.s
405ea9
@@ -0,0 +1,44 @@
405ea9
+# Copyright 2021 Free Software Foundation, Inc.
405ea9
+
405ea9
+# This program is free software; you can redistribute it and/or modify
405ea9
+# it under the terms of the GNU General Public License as published by
405ea9
+# the Free Software Foundation; either version 3 of the License, or
405ea9
+# (at your option) any later version.
405ea9
+#
405ea9
+# This program is distributed in the hope that it will be useful,
405ea9
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
405ea9
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
405ea9
+# GNU General Public License for more details.
405ea9
+#
405ea9
+# You should have received a copy of the GNU General Public License
405ea9
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
405ea9
+
405ea9
+
405ea9
+# test to verify that the prefixed instructions that
405ea9
+# load/store non-relative values work OK.
405ea9
+
405ea9
+.global main
405ea9
+.type main,function
405ea9
+main:
405ea9
+	nop
405ea9
+	lnia 4
405ea9
+	addi 4,4,40
405ea9
+	plxv 4,4(4),0
405ea9
+	plxv 5,12(4),0
405ea9
+	plxv 6,20(4),0
405ea9
+	plxv 7,28(4),0
405ea9
+check_here:
405ea9
+	blr
405ea9
+mydata:
405ea9
+	.long 0xa1b1c1d1	# <<-
405ea9
+	.long 0xa2b2c2d2	# <<- loaded into vs4
405ea9
+	.long 0xa3b3c3d3	# <<- loaded into vs4
405ea9
+	.long 0xa4b4c4d4	# <<- loaded into vs4, vs5
405ea9
+	.long 0xa5b5c5d5	# <<- loaded into vs4, vs5
405ea9
+	.long 0xa6b6c6d6	# <<- loaded into      vs5, vs6
405ea9
+	.long 0xa7b7c7d7	# <<- loaded into      vs5, vs6
405ea9
+	.long 0xa8b8c8d8	# <<- loaded into           vs6, vs7
405ea9
+	.long 0xa9b9c9d9	# <<- loaded into           vs6, vs7
405ea9
+	.long 0xaabacada	# <<- loaded into                vs7
405ea9
+	.long 0xabbbcbdb	# <<- loaded into                vs7
405ea9
+	.long 0xacbcccdc	# <<-