Blob Blame History Raw
commit 3950c5d661ee09526cddcf24daf5fc22bc83f70c
Author: Carl Love <cel@us.ibm.com>
Date:   Mon Nov 1 11:18:32 2021 -0500

    Valgrind Add powerpc R=1 tests
    
    Contributed by Will Schmidt <will_schmidt@vnet.ibm.com>
    
    This includes updates and adjustments as suggested by Carl.
    
    Add tests that exercise PCRelative instructions.
    These instructions are encoded with R==1, which indicate that
    the memory accessed by the instruction is at a location
    relative to the currently executing instruction.
    
    These tests are built using -Wl,-text and -Wl,-bss
    options to ensure the location of the target array is at a
    location with a specific offset from the currently
    executing instruction.
    
    The write instructions are aimed at a large buffer in
    the bss section; which is checked for updates at the
    completion of each test.
    
    In order to ensure consistent output across assorted
    systems, the tests have been padded with ori, nop instructions
    and align directives.
    
    Detailed changes:
     * Makefile.am: Add test_isa_3_1_R1_RT and test_isa_3_1_R1_XT tests.
     * isa_3_1_helpers.h: Add identify_instruction_by_func_name() helper function
       to indicate if the test is for R==1.
       Add helpers to initialize and print changes to the pcrelative_write_target
       array.
       Add #define to help pad code with a series of eyecatcher ORI instructions.
         * test_isa_3_1_R1_RT.c: New test.
         * test_isa_3_1_R1_XT.c: New test.
         * test_isa_3_1_R1_XT.stdout.exp: New expected output.
         * test_isa_3_1_R1_XT.stdout.exp: New expected output.
         * test_isa_3_1_R1_RT.stderr.exp: New expected output.
         * test_isa_3_1_R1_RT.stderr.exp: New expected output.
    
         * test_isa_3_1_R1_RT.vgtest: New test handler.
         * test_isa_3_1_R1_XT.vgtest: New test handler.
    
         * test_isa_3_1_common.c: Add indicators (updates_byte,updates_halfword,
           updates_word) indicators to control the output from the R==1 tests.
           Add helper check for "_R1" to indicate if instruction is coded with R==1.
           Add init and print helpers for the pcrelative_write_target array.

diff --git a/none/tests/ppc64/Makefile.am b/none/tests/ppc64/Makefile.am
index b709f3ef4..f8eab9fc0 100644
--- a/none/tests/ppc64/Makefile.am
+++ b/none/tests/ppc64/Makefile.am
@@ -61,6 +61,8 @@ EXTRA_DIST = \
 	test_isa_3_1_VRT.vgtest test_isa_3_1_VRT.stderr.exp test_isa_3_1_VRT.stdout.exp \
 	test_isa_3_1_Misc.vgtest test_isa_3_1_Misc.stderr.exp test_isa_3_1_Misc.stdout.exp \
 	test_isa_3_1_AT.vgtest test_isa_3_1_AT.stderr.exp test_isa_3_1_AT.stdout.exp \
+	test_isa_3_1_R1_RT.vgtest test_isa_3_1_R1_RT.stderr.exp test_isa_3_1_R1_RT.stdout.exp \
+	test_isa_3_1_R1_XT.vgtest test_isa_3_1_R1_XT.stderr.exp test_isa_3_1_R1_XT.stdout.exp \
 	subnormal_test.stderr.exp  subnormal_test.stdout.exp \
 	subnormal_test.vgtest test_darn_inst.stderr.exp \
 	test_darn_inst.stdout.exp test_darn_inst.vgtest \
@@ -68,8 +70,8 @@ EXTRA_DIST = \
 	test_copy_paste.stderr.exp test_copy_paste.stdout.exp \
 	test_copy_paste.vgtest \
 	test_mcrxrx.vgtest test_mcrxrx.stderr.exp test_mcrxrx.stdout.exp \
-	test_lxvx_stxvx.vgtest test_lxvx_stxvx.stderr.exp test_lxvx_stxvx.stdout.exp-p8  test_lxvx_stxvx.stdout.exp-p9
-
+	test_lxvx_stxvx.vgtest test_lxvx_stxvx.stderr.exp \
+	test_lxvx_stxvx.stdout.exp-p8  test_lxvx_stxvx.stdout.exp-p9
 
 check_PROGRAMS = \
 	allexec \
@@ -80,11 +82,12 @@ check_PROGRAMS = \
 	test_isa_3_0 test_mod_instructions \
 	test_isa_3_1_RT test_isa_3_1_XT test_isa_3_1_VRT \
 	test_isa_3_1_Misc test_isa_3_1_AT \
+	test_isa_3_1_R1_RT test_isa_3_1_R1_XT \
 	subnormal_test test_darn_inst test_copy_paste \
 	test_tm test_touch_tm data-cache-instructions \
 	std_reg_imm \
 	twi_tdi tw_td power6_bcmp scv_test \
-	test_mcrxrx  test_lxvx_stxvx
+	test_mcrxrx test_lxvx_stxvx
 
 # lmw, stmw, lswi, lswx, stswi, stswx compile (and run) only on big endian.
 if VGCONF_PLATFORMS_INCLUDE_PPC64BE_LINUX
@@ -106,6 +109,8 @@ test_isa_3_1_RT_SOURCES = test_isa_3_1_RT.c test_isa_3_1_common.c
 test_isa_3_1_VRT_SOURCES = test_isa_3_1_VRT.c test_isa_3_1_common.c
 test_isa_3_1_Misc_SOURCES = test_isa_3_1_Misc.c test_isa_3_1_common.c
 test_isa_3_1_AT_SOURCES = test_isa_3_1_AT.c test_isa_3_1_common.c
+test_isa_3_1_R1_XT_SOURCES = test_isa_3_1_R1_XT.c test_isa_3_1_common.c
+test_isa_3_1_R1_RT_SOURCES = test_isa_3_1_R1_RT.c test_isa_3_1_common.c
 test_darn_inst_SOURCES = test_darn_inst.c
 
 if HAS_ALTIVEC
@@ -224,6 +229,11 @@ test_isa_3_1_VRT_CFLAGS = $(test_isa_3_1_CFLAGS)
 test_isa_3_1_Misc_CFLAGS = $(test_isa_3_1_CFLAGS)
 test_isa_3_1_AT_CFLAGS = $(test_isa_3_1_CFLAGS)
 
+# The _R1_foo tests exercise pc-relative instructions, so require the bss and text sections
+# exist at known offsets with respect to each other.
+test_isa_3_1_R1_RT_CFLAGS = $(test_isa_3_1_CFLAGS) -Wl,-Tbss,0x20000 -Wl,-Ttext,0x40000
+test_isa_3_1_R1_XT_CFLAGS = $(test_isa_3_1_CFLAGS) -Wl,-Tbss,0x20000 -Wl,-Ttext,0x40000
+
 subnormal_test_CFLAGS = $(AM_CFLAGS) -Winline -Wall -O -g -mregnames $(VSX_FLAG) $(ISA_2_06_FLAG) \
 			@FLAG_M64@ $(ALTIVEC_FLAG) $(BUILD_FLAG_VSX) $(BUILD_FLAGS_ISA_2_06)
 
diff --git a/none/tests/ppc64/isa_3_1_helpers.h b/none/tests/ppc64/isa_3_1_helpers.h
index 338f55526..716a6277b 100644
--- a/none/tests/ppc64/isa_3_1_helpers.h
+++ b/none/tests/ppc64/isa_3_1_helpers.h
@@ -43,6 +43,9 @@ extern void debug_show_current_iteration();
 extern void debug_dump_buffer();
 
 extern void identify_form_components(const char *, const char *);
+extern void identify_instruction_by_func_name(const char *);
+extern void init_pcrelative_write_target();
+extern void print_pcrelative_write_target();
 extern void dump_vsxargs();
 extern void generic_prologue();
 extern void build_args_table();
@@ -58,6 +61,21 @@ extern void initialize_source_registers();
 extern void set_up_iterators();
 extern void initialize_buffer(int);
 
+/* This (TEXT_BSS_DELTA) is the relative distance between those
+   sections as set by the linker options for the R==1 tests. */
+#define TEXT_BSS_DELTA 0x20000
+#define RELOC_BUFFER_SIZE 0x1000
+extern unsigned long long pcrelative_buff_addr(int);
+#define PAD_ORI	\
+	__asm__ __volatile__ ("ori 21,21,21"); \
+	__asm__ __volatile__ ("ori 22,22,22");\
+	__asm__ __volatile__ ("ori 23,23,23");\
+	__asm__ __volatile__ ("ori 24,24,24");\
+	__asm__ __volatile__ ("ori 25,25,25");\
+	__asm__ __volatile__ ("ori 26,26,26");\
+	__asm__ __volatile__ ("ori 27,27,27");\
+	__asm__ __volatile__ ("ori 28,28,28");
+
 extern int verbose;
 #define debug_printf(X) if (verbose>0) printf(X);
 #define debug_show_labels (verbose>0)
diff --git a/none/tests/ppc64/test_isa_3_1_R1_RT.c b/none/tests/ppc64/test_isa_3_1_R1_RT.c
new file mode 100644
index 000000000..d73b84b10
--- /dev/null
+++ b/none/tests/ppc64/test_isa_3_1_R1_RT.c
@@ -0,0 +1,624 @@
+/*
+ * Valgrind testcase for PowerPC ISA 3.1
+ *
+ * Copyright (C) 2019-2020 Will Schmidt <will_schmidt@vnet.ibm.com>
+ *
+ * 64bit build:
+ *    gcc -Winline -Wall -g -O -mregnames -maltivec -m64
+ */
+
+/*
+ *   This program is free software; you can redistribute it and/or
+ *   modify it under the terms of the GNU General Public License as
+ *   published by the Free Software Foundation; either version 2 of the
+ *   License, or (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include <stdio.h>
+#ifdef HAS_ISA_3_1
+#include <stdint.h>
+#include <assert.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <altivec.h>
+#include <malloc.h>
+
+#include <string.h>
+#include <signal.h>
+#include <setjmp.h>
+
+/* Condition Register fields.
+   These are used to capture the condition register values immediately after
+   the instruction under test is executed. This is done to help prevent other
+   test overhead (switch statements, result compares, etc) from disturbing
+   the test case results.  */
+unsigned long current_cr;
+unsigned long current_fpscr;
+
+struct test_list_t current_test;
+
+#include "isa_3_1_helpers.h"
+
+static void test_plxvp_off0_R1 (void) {
+	PAD_ORI
+  __asm__ __volatile__ ("plxvp 20, +0(0),1"  );
+	PAD_ORI
+}
+static void test_plxvp_off8_R1 (void) {
+	PAD_ORI
+  __asm__ __volatile__ ("plxvp 20, +8(0),1" );
+	PAD_ORI
+}
+static void test_plxvp_off16_R1 (void) {
+	PAD_ORI
+  __asm__ __volatile__ ("plxvp 20, +16(0),1" );
+	PAD_ORI
+}
+static void test_plxvp_off24_R1 (void) {
+	PAD_ORI
+  __asm__ __volatile__ ("plxvp 20, +24(0),1" );
+	PAD_ORI
+}
+static void test_plxvp_off32_R1 (void) {
+	PAD_ORI
+  __asm__ __volatile__ ("plxvp 20, +32(0),1" );
+	PAD_ORI
+}
+static void test_plbz_off0_R1 (void) {
+	PAD_ORI
+  __asm__ __volatile__ ("plbz %0, +0(0), 1" : "=r" (rt) );
+	PAD_ORI
+}
+static void test_plbz_off8_R1 (void) {
+	PAD_ORI
+  __asm__ __volatile__ ("plbz %0, +8(0), 1" : "=r" (rt) );
+	PAD_ORI
+}
+static void test_plbz_off16_R1 (void) {
+	PAD_ORI
+  __asm__ __volatile__ ("plbz %0, +16(0), 1" : "=r" (rt) );
+	PAD_ORI
+}
+static void test_plbz_off32_R1 (void) {
+	PAD_ORI
+  __asm__ __volatile__ ("plbz %0, +32(0), 1" : "=r" (rt) );
+	PAD_ORI
+}
+static void test_plbz_off64_R1 (void) {
+	PAD_ORI
+  __asm__ __volatile__ ("plbz %0, +64(0), 1" : "=r" (rt) );
+	PAD_ORI
+	PAD_ORI
+}
+static void test_plhz_off0_R1 (void) {
+	PAD_ORI
+  __asm__ __volatile__ ("plhz %0, +0(0), 1" : "=r" (rt) );
+	PAD_ORI
+}
+static void test_plhz_off8_R1 (void) {
+	PAD_ORI
+  __asm__ __volatile__ ("plhz %0, +8(0), 1" : "=r" (rt) );
+	PAD_ORI
+}
+static void test_plhz_off16_R1 (void) {
+	PAD_ORI
+  __asm__ __volatile__ ("plhz %0, +16(0), 1" : "=r" (rt) );
+	PAD_ORI
+}
+static void test_plhz_off32_R1 (void) {
+	PAD_ORI
+  __asm__ __volatile__ ("plhz %0, +32(0), 1" : "=r" (rt) );
+	PAD_ORI
+}
+static void test_plhz_off64_R1 (void) {
+	PAD_ORI
+  __asm__ __volatile__ ("plhz %0, +64(0), 1" : "=r" (rt) );
+	PAD_ORI
+	PAD_ORI
+}
+static void test_plha_off0_R1 (void) {
+	PAD_ORI
+  __asm__ __volatile__ ("plha %0, +0(0), 1" : "=r" (rt) );
+	PAD_ORI
+}
+static void test_plha_off8_R1 (void) {
+	PAD_ORI
+  __asm__ __volatile__ ("plha %0, +8(0), 1" : "=r" (rt)  );
+	PAD_ORI
+}
+static void test_plha_off16_R1 (void) {
+	PAD_ORI
+  __asm__ __volatile__ ("plha %0, +16(0), 1" : "=r" (rt) );
+	PAD_ORI
+}
+static void test_plha_off32_R1 (void) {
+	PAD_ORI
+  __asm__ __volatile__ ("plha %0, +32(0), 1" : "=r" (rt) );
+	PAD_ORI
+}
+static void test_plha_off64_R1 (void) {
+	PAD_ORI
+  __asm__ __volatile__ ("plha %0, +64(0), 1" : "=r" (rt) );
+	PAD_ORI
+	PAD_ORI
+}
+static void test_plwz_off0_R1 (void) {
+  __asm__ __volatile__ ("plwz %0, +0(0), 1" : "=r" (rt)  );
+}
+static void test_plwz_off8_R1 (void) {
+  __asm__ __volatile__ ("plwz %0, +8(0), 1" : "=r" (rt) );
+}
+static void test_plwz_off16_R1 (void) {
+  __asm__ __volatile__ ("plwz %0, +16(0), 1" : "=r" (rt) );
+}
+static void test_plwz_off32_R1 (void) {
+	PAD_ORI
+  __asm__ __volatile__ ("plwz %0, +32(0), 1" : "=r" (rt) );
+	PAD_ORI
+}
+static void test_plwz_off64_R1 (void) {
+	PAD_ORI
+  __asm__ __volatile__ ("plwz %0, +64(0), 1" : "=r" (rt) );
+	PAD_ORI
+	PAD_ORI
+}
+static void test_plwa_off0_R1 (void) {
+  __asm__ __volatile__ ("plwa %0, +0(0), 1" : "=r" (rt)  );
+}
+static void test_plwa_off8_R1 (void) {
+  __asm__ __volatile__ ("plwa %0, +8(0), 1" : "=r" (rt)  );
+}
+static void test_plwa_off16_R1 (void) {
+  __asm__ __volatile__ ("plwa %0, +16(0), 1" : "=r" (rt) );
+}
+static void test_plwa_off32_R1 (void) {
+	PAD_ORI
+  __asm__ __volatile__ ("plwa %0, +32(0), 1" : "=r" (rt) );
+	PAD_ORI
+}
+static void test_plwa_off64_R1 (void) {
+	PAD_ORI
+  __asm__ __volatile__ ("plwa %0, +64(0), 1" : "=r" (rt) );
+	PAD_ORI
+	PAD_ORI
+}
+static void test_pld_off0_R1 (void) {
+  __asm__ __volatile__ ("pld %0, +0(0), 1" : "=r" (rt)  );
+}
+static void test_pld_off8_R1 (void) {
+  __asm__ __volatile__ ("pld %0, +8(0), 1" : "=r" (rt)  );
+}
+static void test_pld_off16_R1 (void) {
+	PAD_ORI
+  __asm__ __volatile__ ("pld %0, +16(0), 1" : "=r" (rt) );
+	PAD_ORI
+}
+static void test_pld_off32_R1 (void) {
+	PAD_ORI
+  __asm__ __volatile__ ("pld %0, +32(0), 1" : "=r" (rt) );
+	PAD_ORI
+}
+static void test_pld_off64_R1 (void) {
+	PAD_ORI
+  __asm__ __volatile__ ("pld %0, +64(0), 1" : "=r" (rt) );
+	PAD_ORI
+	PAD_ORI
+}
+static void test_pstb_off0_R1 (void) {
+  __asm__ __volatile__ ("pstb %0, -0x1f400+0(0), 1" :: "r" (rs) );
+}
+static void test_pstb_off8_R1 (void) {
+  __asm__ __volatile__ ("pstb %0, -0x1f400+8(0), 1" :: "r" (rs) );
+}
+static void test_pstb_off16_R1 (void) {
+  __asm__ __volatile__ ("pstb %0, -0x1f400+16(0), 1" :: "r" (rs) );
+}
+static void test_pstb_off32_R1 (void) {
+  __asm__ __volatile__ ("pstb %0, -0x1f400+32(0), 1" :: "r" (rs) );
+}
+static void test_psth_off0_R1 (void) {
+  __asm__ __volatile__ ("psth %0, -0x1f400+0(0), 1" :: "r" (rs) );
+}
+static void test_psth_off8_R1 (void) {
+  __asm__ __volatile__ ("psth %0, -0x1f400+8(0), 1" :: "r" (rs) );
+}
+static void test_psth_off16_R1 (void) {
+  __asm__ __volatile__ ("psth %0, -0x1f400+16(0), 1" :: "r" (rs) );
+}
+static void test_psth_off32_R1 (void) {
+  __asm__ __volatile__ ("psth %0, -0x1f400+32(0), 1" :: "r" (rs) );
+}
+static void test_pstw_off0_R1 (void) {
+  __asm__ __volatile__ ("pstw %0, -0x1f400+0(0), 1" :: "r" (rs) );
+}
+static void test_pstw_off8_R1 (void) {
+  __asm__ __volatile__ ("pstw %0, -0x1f400+8(0), 1" :: "r" (rs) );
+}
+static void test_pstw_off16_R1 (void) {
+  __asm__ __volatile__ ("pstw %0, -0x1f400+16(0), 1" :: "r" (rs) );
+}
+static void test_pstw_off32_R1 (void) {
+  __asm__ __volatile__ ("pstw %0, -0x1f400+32(0), 1" :: "r" (rs) );
+}
+static void test_pstd_off0_R1 (void) {
+  __asm__ __volatile__ ("pstd %0, -0x1f400+0(0), 1" :: "r" (rs) );
+}
+static void test_pstd_off8_R1 (void) {
+  __asm__ __volatile__ ("pstd %0, -0x1f400+8(0), 1" :: "r" (rs) );
+}
+static void test_pstd_off16_R1 (void) {
+  __asm__ __volatile__ ("pstd %0, -0x1f400+16(0), 1" :: "r" (rs) );
+}
+static void test_pstd_off32_R1 (void) {
+  __asm__ __volatile__ ("pstd %0, -0x1f400+32(0), 1" :: "r" (rs) );
+}
+  /* For the paddi tests; although we can get close to a read/write target
+     due to forcing where the .text and .bss sections are placed, there is
+     still enough codegen variability that having a raw value in the exp
+     file will not be determinative for these instructions.
+     Thus, compromise and just ensure that the generated value is an
+     address that lands within the reloc buffer, and use quasi magic
+     eyecatcher values in the return to indicate success.  */
+static void test_paddi_0_R1 (void) {
+  __asm__ __volatile__ ("paddi %0, 0, 0+0, 1" : "=r" (rt)  );
+  rt = rt - TEXT_BSS_DELTA;
+  if (rt > pcrelative_buff_addr(0) &&
+		  rt < pcrelative_buff_addr(RELOC_BUFFER_SIZE))
+	  rt = 0xffff0000;
+}
+static void test_paddi_12_R1 (void) {
+  __asm__ __volatile__ ("paddi %0, 0, 0+12, 1" : "=r" (rt)  );
+  rt = rt - TEXT_BSS_DELTA;
+  if (rt > pcrelative_buff_addr(0) &&
+		  rt < pcrelative_buff_addr(RELOC_BUFFER_SIZE))
+	  rt = 0xffff0012;
+}
+static void test_paddi_48_R1 (void) {
+  __asm__ __volatile__ ("paddi %0, 0, 0+48, 1" : "=r" (rt)  );
+  rt = rt - TEXT_BSS_DELTA;
+  if (rt > pcrelative_buff_addr(0) &&
+		  rt < pcrelative_buff_addr(RELOC_BUFFER_SIZE))
+	  rt = 0xffff0048;
+}
+static void test_paddi_98_R1 (void) {
+  __asm__ __volatile__ ("paddi %0, 0, 0+98, 1" : "=r" (rt) );
+  rt = rt - TEXT_BSS_DELTA;
+  if (rt > pcrelative_buff_addr(0) &&
+		  rt < pcrelative_buff_addr(RELOC_BUFFER_SIZE))
+	  rt = 0xffff0098;
+}
+static void test_plq_off0_R1 (void) {
+	PAD_ORI
+  __asm__ __volatile__ ("plq 26, +0(0), 1"  );
+	PAD_ORI
+}
+static void test_plq_off8_R1 (void) {
+	PAD_ORI
+  __asm__ __volatile__ ("plq 26, +8(0), 1"  );
+	PAD_ORI
+}
+static void test_plq_off16_R1 (void) {
+	PAD_ORI
+  __asm__ __volatile__ ("plq 26, +16(0), 1"  );
+	PAD_ORI
+}
+static void test_plq_off32_R1 (void) {
+	PAD_ORI
+  __asm__ __volatile__ ("plq 26, +32(0), 1"  );
+	PAD_ORI
+}
+static void test_plq_off48_R1 (void) {
+	PAD_ORI
+  __asm__ __volatile__ ("plq 26, +48(0), 1"  );
+	PAD_ORI
+}
+static void test_plq_off64_R1 (void) {
+	PAD_ORI
+  __asm__ __volatile__ ("plq 26, +64(0), 1"  );
+	PAD_ORI
+	PAD_ORI
+}
+static void test_pstq_off0_R1 (void) {
+  __asm__ __volatile__ ("pstq 24, -0x1f400+0(0), 1"  );
+}
+static void test_pstq_off8_R1 (void) {
+  __asm__ __volatile__ ("pstq 24, -0x1f400+8(0), 1"  );
+}
+static void test_pstq_off16_R1 (void) {
+  __asm__ __volatile__ ("pstq 24, -0x1f400+16(0), 1"  );
+}
+static void test_pstq_off32_R1 (void) {
+  __asm__ __volatile__ ("pstq 24, -0x1f400+32(0), 1"  );
+}
+static void test_pstq_off64_R1 (void) {
+  __asm__ __volatile__ ("pstq 24, -0x1f400+64(0), 1"  );
+}
+
+static test_list_t testgroup_generic[] = {
+  { &test_paddi_0_R1, "paddi 0_R1", "RT,RA,SI,R"}, /* bcwp */
+  { &test_paddi_12_R1, "paddi 12_R1", "RT,RA,SI,R"}, /* bcwp */
+  { &test_paddi_48_R1, "paddi 48_R1", "RT,RA,SI,R"}, /* bcwp */
+  { &test_paddi_98_R1, "paddi 98_R1", "RT,RA,SI,R"}, /* bcwp */
+  { &test_plbz_off0_R1, "plbz off0_R1", "RT,D(RA),R"}, /* bcwp */
+  { &test_plbz_off8_R1, "plbz off8_R1", "RT,D(RA),R"}, /* bcwp */
+  { &test_plbz_off16_R1, "plbz off16_R1", "RT,D(RA),R"}, /* bcwp */
+  { &test_plbz_off32_R1, "plbz off32_R1", "RT,D(RA),R"}, /* bcwp */
+  { &test_plbz_off64_R1, "plbz off64_R1", "RT,D(RA),R"}, /* bcwp */
+  { &test_pld_off0_R1, "pld off0_R1", "RT,D(RA),R"}, /* bcwp */
+  { &test_pld_off8_R1, "pld off8_R1", "RT,D(RA),R"}, /* bcwp */
+  { &test_pld_off16_R1, "pld off16_R1", "RT,D(RA),R"}, /* bcwp */
+  { &test_pld_off32_R1, "pld off32_R1", "RT,D(RA),R"}, /* bcwp */
+  { &test_pld_off64_R1, "pld off64_R1", "RT,D(RA),R"}, /* bcwp */
+  { &test_plha_off0_R1, "plha off0_R1", "RT,D(RA),R"}, /* bcwp */
+  { &test_plha_off8_R1, "plha off8_R1", "RT,D(RA),R"}, /* bcwp */
+  { &test_plha_off16_R1, "plha off16_R1", "RT,D(RA),R"}, /* bcwp */
+  { &test_plha_off32_R1, "plha off32_R1", "RT,D(RA),R"}, /* bcwp */
+  { &test_plha_off64_R1, "plha off64_R1", "RT,D(RA),R"}, /* bcwp */
+  { &test_plhz_off0_R1, "plhz off0_R1", "RT,D(RA),R"}, /* bcwp */
+  { &test_plhz_off8_R1, "plhz off8_R1", "RT,D(RA),R"}, /* bcwp */
+  { &test_plhz_off16_R1, "plhz off16_R1", "RT,D(RA),R"}, /* bcwp */
+  { &test_plhz_off32_R1, "plhz off32_R1", "RT,D(RA),R"}, /* bcwp */
+  { &test_plhz_off64_R1, "plhz off64_R1", "RT,D(RA),R"}, /* bcwp */
+  { &test_plq_off0_R1, "plq off0_R1", "RTp,D(RA),R"}, /* bcwp */
+  { &test_plq_off8_R1, "plq off8_R1", "RTp,D(RA),R"}, /* bcwp */
+  { &test_plq_off16_R1, "plq off16_R1", "RTp,D(RA),R"}, /* bcwp */
+  { &test_plq_off32_R1, "plq off32_R1", "RTp,D(RA),R"}, /* bcwp */
+  { &test_plq_off48_R1, "plq off48_R1", "RTp,D(RA),R"}, /* bcwp */
+  { &test_plq_off64_R1, "plq off64_R1", "RTp,D(RA),R"}, /* bcwp */
+  { &test_plwa_off0_R1, "plwa off0_R1", "RT,D(RA),R"}, /* bcwp */
+  { &test_plwa_off8_R1, "plwa off8_R1", "RT,D(RA),R"}, /* bcwp */
+  { &test_plwa_off16_R1, "plwa off16_R1", "RT,D(RA),R"}, /* bcwp */
+  { &test_plwa_off32_R1, "plwa off32_R1", "RT,D(RA),R"}, /* bcwp */
+  { &test_plwa_off64_R1, "plwa off64_R1", "RT,D(RA),R"}, /* bcwp */
+  { &test_plwz_off0_R1, "plwz off0_R1", "RT,D(RA),R"}, /* bcwp */
+  { &test_plwz_off8_R1, "plwz off8_R1", "RT,D(RA),R"}, /* bcwp */
+  { &test_plwz_off16_R1, "plwz off16_R1", "RT,D(RA),R"}, /* bcwp */
+  { &test_plwz_off32_R1, "plwz off32_R1", "RT,D(RA),R"}, /* bcwp */
+  { &test_plwz_off64_R1, "plwz off64_R1", "RT,D(RA),R"}, /* bcwp */
+  { &test_plxvp_off0_R1, "plxvp off0_R1", "XTp,D(RA),R"}, /* bcwp */
+  { &test_plxvp_off8_R1, "plxvp off8_R1", "XTp,D(RA),R"}, /* bcwp */
+  { &test_plxvp_off16_R1, "plxvp off16_R1", "XTp,D(RA),R"}, /* bcwp */
+  { &test_plxvp_off24_R1, "plxvp off24_R1", "XTp,D(RA),R"}, /* bcwp */
+  { &test_plxvp_off32_R1, "plxvp off32_R1", "XTp,D(RA),R"}, /* bcwp */
+  { &test_pstb_off0_R1, "pstb off0_R1", "RS,D(RA),R"}, /* bcwp */
+  { &test_pstb_off8_R1, "pstb off8_R1", "RS,D(RA),R"}, /* bcwp */
+  { &test_pstb_off16_R1, "pstb off16_R1", "RS,D(RA),R"}, /* bcwp */
+  { &test_pstb_off32_R1, "pstb off32_R1", "RS,D(RA),R"}, /* bcwp */
+  { &test_pstd_off0_R1, "pstd off0_R1", "RS,D(RA),R"}, /* bcwp */
+  { &test_pstd_off8_R1, "pstd off8_R1", "RS,D(RA),R"}, /* bcwp */
+  { &test_pstd_off16_R1, "pstd off16_R1", "RS,D(RA),R"}, /* bcwp */
+  { &test_pstd_off32_R1, "pstd off32_R1", "RS,D(RA),R"}, /* bcwp */
+  { &test_psth_off0_R1, "psth off0_R1", "RS,D(RA),R"}, /* bcwp */
+  { &test_psth_off8_R1, "psth off8_R1", "RS,D(RA),R"}, /* bcwp */
+  { &test_psth_off16_R1, "psth off16_R1", "RS,D(RA),R"}, /* bcwp */
+  { &test_psth_off32_R1, "psth off32_R1", "RS,D(RA),R"}, /* bcwp */
+  { &test_pstq_off0_R1, "pstq off0_R1", "RSp,D(RA),R"}, /* bcwp */
+  { &test_pstq_off8_R1, "pstq off8_R1", "RSp,D(RA),R"}, /* bcwp */
+  { &test_pstq_off16_R1, "pstq off16_R1", "RSp,D(RA),R"}, /* bcwp */
+  { &test_pstq_off32_R1, "pstq off32_R1", "RSp,D(RA),R"}, /* bcwp */
+  { &test_pstq_off64_R1, "pstq off64_R1", "RSp,D(RA),R"}, /* bcwp */
+  { &test_pstw_off0_R1, "pstw off0_R1", "RS,D(RA),R"}, /* bcwp */
+  { &test_pstw_off8_R1, "pstw off8_R1", "RS,D(RA),R"}, /* bcwp */
+  { &test_pstw_off16_R1, "pstw off16_R1", "RS,D(RA),R"}, /* bcwp */
+  { &test_pstw_off32_R1, "pstw off32_R1", "RS,D(RA),R"}, /* bcwp */
+	{ NULL, 	    NULL },
+};
+
+/*  Allow skipping of tests. */
+unsigned long test_count=0xffff;
+unsigned long skip_count=0;
+unsigned long setup_only=0;
+
+/*  Set up a setjmp/longjmp to gently handle our SIGILLs and SIGSEGVs.  */
+static jmp_buf mybuf;
+
+/* This (testfunction_generic) is meant to handle all of the instruction
+   variations.  The helpers set up the register and iterator values
+   as is appropriate for the instruction being tested.  */
+static void testfunction_generic (const char* instruction_name,
+				  test_func_t test_function,
+				  unsigned int ignore_flags,
+				  char * cur_form) {
+
+   identify_form_components (instruction_name , cur_form);
+   debug_show_form (instruction_name, cur_form);
+   set_up_iterators ();
+   debug_show_iter_ranges ();
+   initialize_buffer (0);
+   init_pcrelative_write_target ();
+   debug_dump_buffer ();
+
+   for (vrai = a_start; vrai < a_iters ; vrai+=a_inc) {
+      for (vrbi = b_start; vrbi < b_iters ; vrbi+=b_inc) {
+	 for (vrci = c_start; vrci < c_iters ; vrci+=c_inc) {
+	    for (vrmi = m_start; (vrmi < m_iters) ; vrmi+=m_inc) {
+		CHECK_OVERRIDES
+		debug_show_current_iteration ();
+		// Be sure to initialize the target registers first.
+		initialize_target_registers ();
+		initialize_source_registers ();
+		printf ("%s", instruction_name);
+		print_register_header ();
+		printf( " =>"); fflush (stdout);
+		if (!setup_only) {
+		  if (enable_setjmp) {
+		   if ( setjmp ( mybuf ) ) {
+		     printf("signal tripped. (FIXME)\n");
+		     continue;
+		   }
+		  }
+		  (*test_function) ();
+		}
+		print_register_footer ();
+		print_result_buffer ();
+		print_pcrelative_write_target ();
+		printf ("\n");
+	    }
+	 }
+      }
+   }
+}
+
+void mykillhandler ( int x ) { longjmp (mybuf, 1); }
+void mysegvhandler ( int x ) { longjmp (mybuf, 1); }
+
+static void do_tests ( void )
+{
+   int groupcount;
+   char * cur_form;
+   test_group_t group_function = &testfunction_generic;
+   test_list_t *tests = testgroup_generic;
+
+   struct sigaction kill_action, segv_action;
+   struct sigaction old_kill_action, old_segv_action;
+   if (enable_setjmp) {
+      kill_action.sa_handler = mykillhandler;
+      segv_action.sa_handler = mysegvhandler;
+      sigemptyset ( &kill_action.sa_mask );
+      sigemptyset ( &segv_action.sa_mask );
+      kill_action.sa_flags = SA_NODEFER;
+      segv_action.sa_flags = SA_NODEFER;
+      sigaction ( SIGILL, &kill_action, &old_kill_action);
+      sigaction ( SIGSEGV, &segv_action, &old_segv_action);
+   }
+
+   for (groupcount = 0; tests[groupcount].name != NULL; groupcount++) {
+	cur_form = strdup(tests[groupcount].form);
+	current_test = tests[groupcount];
+	identify_instruction_by_func_name (current_test.name);
+	if (groupcount < skip_count) continue;
+	if (verbose) printf("Test #%d ,", groupcount);
+	if (verbose > 1) printf(" instruction %s (v=%d)", current_test.name, verbose);
+	(*group_function) (current_test.name, current_test.func, 0, cur_form );
+	printf ("\n");
+	if (groupcount >= (skip_count+test_count)) break;
+   }
+   if (debug_show_labels) printf("\n");
+   printf ("All done. Tested %d different instruction groups\n", groupcount);
+}
+
+static void usage (void)
+{
+   fprintf(stderr,
+      "Usage: test_isa_XXX [OPTIONS]\n"
+      "\t-h: display this help and exit\n"
+      "\t-v: increase verbosity\n"
+      "\t-a <foo> : limit number of a-iterations to <foo>\n"
+      "\t-b <foo> : limit number of b-iterations to <foo>\n"
+      "\t-c <foo> : limit number of c-iterations to <foo>\n"
+      "\t-n <foo> : limit to this number of tests.\n"
+      "\t-r <foo>: run only test # <foo> \n"
+      "\t\n"
+      "\t-j :enable setjmp to recover from illegal insns. \n"
+      "\t-m :(dev only?) lock VRM value to zero.\n"
+      "\t-z :(dev only?) lock MC value to zero.\n"
+      "\t-p :(dev only?) disable prefix instructions\n"
+      "\t-s <foo>: skip <foo> tests \n"
+      "\t-c <foo>: stop after running <foo> # of tests \n"
+      "\t-f : Do the test setup but do not actually execute the test instruction. \n"
+   );
+}
+
+int main (int argc, char **argv)
+{
+   int c;
+   while ((c = getopt(argc, argv, "dhjvmpfzs:a:b:c:n:r:")) != -1) {
+      switch (c) {
+	 case 'h':
+	    usage();
+	    return 0;
+
+	 case 'v':
+	    verbose++;
+	    break;
+
+	 /* Options related to limiting the test iterations.  */
+	 case 'a':
+	    a_limit=atoi (optarg);
+	    printf ("limiting a-iters to %ld.\n", a_limit);
+	    break;
+	 case 'b':
+	    b_limit=atoi (optarg);
+	    printf ("limiting b-iters to %ld.\n", b_limit);
+	    break;
+	 case 'c':
+	    c_limit=atoi (optarg);
+	    printf ("limiting c-iters to %ld.\n", c_limit);
+	    break;
+	 case 'n': // run this number of tests.
+	    test_count=atoi (optarg);
+	    printf ("limiting to %ld tests\n", test_count);
+	    break;
+	 case 'r': // run just test #<foo>.
+	    skip_count=atoi (optarg);
+	    test_count=0;
+	    if (verbose) printf("Running test number %ld\n", skip_count);
+	    break;
+	 case 's': // skip this number of tests.
+	    skip_count=atoi (optarg);
+	    printf ("skipping %ld tests\n", skip_count);
+	    break;
+
+	 /* debug options.  */
+	 case 'd':
+	    dump_tables=1;
+	    printf("DEBUG:dump_tables.\n");
+	    break;
+	 case 'f':
+	    setup_only=1;
+	    printf("DEBUG:setup_only.\n");
+	    break;
+	 case 'j':
+	    enable_setjmp=1;
+	    printf ("DEBUG:setjmp enabled.\n");
+	    break;
+	 case 'm':
+	    vrm_override=1;
+	    printf ("DEBUG:vrm override enabled.\n");
+	    break;
+	 case 'p':
+	    prefix_override=1;
+	    printf ("DEBUG:prefix override enabled.\n");
+	    break;
+	 case 'z':
+	    mc_override=1;
+	    printf ("DEBUG:MC override enabled.\n");
+	    break;
+	 default:
+	    usage();
+	    fprintf(stderr, "Unknown argument: '%c'\n", c);
+	   }
+	}
+
+	generic_prologue ();
+	build_vsx_table ();
+	build_args_table ();
+	build_float_vsx_tables ();
+
+	if (dump_tables) {
+	   dump_float_vsx_tables ();
+	   dump_vsxargs ();
+	}
+
+	do_tests ();
+
+	return 0;
+}
+
+#else	   // HAS_ISA_3_1
+int main (int argc, char **argv)
+{
+   printf("NO ISA 3.1 SUPPORT\n");
+   return 0;
+}
+#endif
diff --git a/none/tests/ppc64/test_isa_3_1_R1_RT.stderr.exp b/none/tests/ppc64/test_isa_3_1_R1_RT.stderr.exp
new file mode 100644
index 000000000..139597f9c
--- /dev/null
+++ b/none/tests/ppc64/test_isa_3_1_R1_RT.stderr.exp
@@ -0,0 +1,2 @@
+
+
diff --git a/none/tests/ppc64/test_isa_3_1_R1_RT.stdout.exp b/none/tests/ppc64/test_isa_3_1_R1_RT.stdout.exp
new file mode 100644
index 000000000..87594748f
--- /dev/null
+++ b/none/tests/ppc64/test_isa_3_1_R1_RT.stdout.exp
@@ -0,0 +1,138 @@
+paddi 0_R1 =>         ffff0000
+
+paddi 12_R1 =>         ffff0012
+
+paddi 48_R1 =>         ffff0048
+
+paddi 98_R1 =>         ffff0098
+
+plbz off0_R1 =>               1a
+
+plbz off8_R1 =>               1f
+
+plbz off16_R1 =>               1f
+
+plbz off32_R1 =>               1b
+
+plbz off64_R1 =>               1b
+
+pld off0_R1 => e740000004100000
+
+pld off8_R1 =>         4e800020
+
+pld off16_R1 => 6318001862f7001f
+
+pld off32_R1 => 639c001c637b001b
+
+pld off64_R1 => 639c001c637b001b
+
+plha off0_R1 =>               1a
+
+plha off8_R1 =>               1f
+
+plha off16_R1 =>               1f
+
+plha off32_R1 =>               1b
+
+plha off64_R1 =>               1b
+
+plhz off0_R1 =>               1a
+
+plhz off8_R1 =>               1f
+
+plhz off16_R1 =>               1f
+
+plhz off32_R1 =>               1b
+
+plhz off64_R1 =>               1b
+
+plq off0_R1 => e34000000410001a 62d6001662b5001f
+
+plq off8_R1 => 62d6001662b5001f 6318001862f7001f
+
+plq off16_R1 => 6318001862f7001f 635a001a6339001b
+
+plq off32_R1 => 639c001c637b001b         4e80003b
+
+plq off48_R1 =>               1a 62d6001662b5001f
+
+plq off64_R1 => 639c001c637b001b         4e80003b
+
+plwa off0_R1 =>          4100000
+
+plwa off8_R1 =>         4e800020
+
+plwa off16_R1 =>                0
+
+plwa off32_R1 =>         637b001b
+
+plwa off64_R1 =>         637b001b
+
+plwz off0_R1 =>          6100000
+
+plwz off8_R1 =>         4e800020
+
+plwz off16_R1 =>                0
+
+plwz off32_R1 =>         637b001b
+
+plwz off64_R1 =>         637b001b
+
+plxvp off0_R1 => 6318001862f70017 635a001a63390019 ea80000004100000 62d6001662b50015
+
+plxvp off8_R1 => 635a001a63390019 639c001c637b001b 62d6001662b50015 6318001862f70017
+
+plxvp off16_R1 => 639c001c637b001b 000000004e800020 6318001862f70017 635a001a63390019
+
+plxvp off24_R1 => 000000004e800020 0000000000000000 635a001a63390019 639c001c637b001b
+
+plxvp off32_R1 => 0000000000000000 62d6001662b50015 639c001c637b001b 000000004e800020
+
+pstb off0_R1 102030405060708 => 08              
+
+pstb off8_R1 102030405060708 => 08              
+
+pstb off16_R1 102030405060708 => 08              
+
+pstb off32_R1 102030405060708 => 08              
+
+pstd off0_R1 102030405060708 => 0102030405060708 
+
+pstd off8_R1 102030405060708 => 0102030405060708 
+
+pstd off16_R1 102030405060708 => 0102030405060708 
+
+pstd off32_R1 102030405060708 => 0102030405060708 
+
+psth off0_R1 102030405060708 => 0708      
+
+psth off8_R1 102030405060708 => 0708      
+
+psth off16_R1 102030405060708 => 0708      
+
+psth off32_R1 102030405060708 => 0708      
+
+pstq off0_R1 102030405060708 a5b4c3d2e1f00918 => 0102030405060708  a5b4c3d2e1f00918 
+pstq off0_R1 102030405060708 a5b4c3d2e1f00918 => 0102030405060708  a5b4c3d2e1f00918 
+
+pstq off8_R1 102030405060708 a5b4c3d2e1f00918 => 0102030405060708  a5b4c3d2e1f00918 
+pstq off8_R1 102030405060708 a5b4c3d2e1f00918 => 0102030405060708  a5b4c3d2e1f00918 
+
+pstq off16_R1 102030405060708 a5b4c3d2e1f00918 => 0102030405060708  a5b4c3d2e1f00918 
+pstq off16_R1 102030405060708 a5b4c3d2e1f00918 => 0102030405060708  a5b4c3d2e1f00918 
+
+pstq off32_R1 102030405060708 a5b4c3d2e1f00918 => 0102030405060708  a5b4c3d2e1f00918 
+pstq off32_R1 102030405060708 a5b4c3d2e1f00918 => 0102030405060708  a5b4c3d2e1f00918 
+
+pstq off64_R1 102030405060708 a5b4c3d2e1f00918 => 0102030405060708  a5b4c3d2e1f00918 
+pstq off64_R1 102030405060708 a5b4c3d2e1f00918 => 0102030405060708  a5b4c3d2e1f00918 
+
+pstw off0_R1 102030405060708 => 05060708  
+
+pstw off8_R1 102030405060708 => 05060708  
+
+pstw off16_R1 102030405060708 => 05060708  
+
+pstw off32_R1 102030405060708 => 05060708  
+
+All done. Tested 66 different instruction groups
diff --git a/none/tests/ppc64/test_isa_3_1_R1_RT.vgtest b/none/tests/ppc64/test_isa_3_1_R1_RT.vgtest
new file mode 100644
index 000000000..61d7f65a1
--- /dev/null
+++ b/none/tests/ppc64/test_isa_3_1_R1_RT.vgtest
@@ -0,0 +1,2 @@
+prereq: ../../../tests/check_ppc64_auxv_cap arch_3_1
+prog: test_isa_3_1_R1_RT
diff --git a/none/tests/ppc64/test_isa_3_1_R1_XT.c b/none/tests/ppc64/test_isa_3_1_R1_XT.c
new file mode 100644
index 000000000..58885b8d3
--- /dev/null
+++ b/none/tests/ppc64/test_isa_3_1_R1_XT.c
@@ -0,0 +1,534 @@
+/*
+ * Valgrind testcase for PowerPC ISA 3.1
+ *
+ * Copyright (C) 2019-2020 Will Schmidt <will_schmidt@vnet.ibm.com>
+ *
+ * 64bit build:
+ *    gcc -Winline -Wall -g -O -mregnames -maltivec -m64
+ */
+
+/*
+ *   This program is free software; you can redistribute it and/or
+ *   modify it under the terms of the GNU General Public License as
+ *   published by the Free Software Foundation; either version 2 of the
+ *   License, or (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include <stdio.h>
+#ifdef HAS_ISA_3_1
+#include <stdint.h>
+#include <assert.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <altivec.h>
+#include <malloc.h>
+
+#include <string.h>
+#include <signal.h>
+#include <setjmp.h>
+
+/* Condition Register fields.
+   These are used to capture the condition register values immediately after
+   the instruction under test is executed. This is done to help prevent other
+   test overhead (switch statements, result compares, etc) from disturbing
+   the test case results.  */
+unsigned long current_cr;
+unsigned long current_fpscr;
+
+struct test_list_t current_test;
+
+#include "isa_3_1_helpers.h"
+static void test_pstxvp_off0_R1 (void) {
+  __asm__ __volatile__ ("pstxvp 20, -0x1f400+0(0),1");
+}
+static void test_pstxvp_off16_R1 (void) {
+  __asm__ __volatile__ ("pstxvp 20, -0x1f400+16(0),1");
+}
+static void test_pstxvp_off32_R1 (void) {
+  __asm__ __volatile__ ("pstxvp 20, -0x1f400+32(0),1");
+}
+static void test_pstxvp_off48_R1 (void) {
+  __asm__ __volatile__ ("pstxvp 20, -0x1f400+48(0),1");
+}
+static void test_plfd_64_R1 (void) {
+  __asm__ __volatile__ ("plfd 28, +64(0), 1");
+	PAD_ORI
+	PAD_ORI
+}
+static void test_plfd_32_R1 (void) {
+  __asm__ __volatile__ ("plfd 28, +32(0), 1");
+	PAD_ORI
+}
+static void test_plfd_16_R1 (void) {
+  __asm__ __volatile__ ("plfd 28, +16(0), 1");
+	PAD_ORI
+}
+static void test_plfd_8_R1 (void) {
+  __asm__ __volatile__ ("plfd 28, +8(0), 1");
+	PAD_ORI
+}
+static void test_plfd_4_R1 (void) {
+  __asm__ __volatile__ ("plfd 28, +4(0), 1");
+	PAD_ORI
+}
+static void test_plfd_0_R1 (void) {
+  __asm__ __volatile__ ("plfd 28, +0(0), 1");
+	PAD_ORI
+}
+static void test_plfs_64_R1 (void) {
+  __asm__ __volatile__ ("plfs 28, +64(0), 1");
+	PAD_ORI
+	PAD_ORI
+}
+static void test_plfs_32_R1 (void) {
+  __asm__ __volatile__ ("plfs 28, +32(0), 1");
+	PAD_ORI
+}
+static void test_plfs_16_R1 (void) {
+  __asm__ __volatile__ ("plfs 28, +16(0), 1");
+	PAD_ORI
+}
+static void test_plfs_8_R1 (void) {
+  __asm__ __volatile__ ("plfs 28, +8(0), 1");
+	PAD_ORI
+}
+static void test_plfs_4_R1 (void) {
+  __asm__ __volatile__ ("plfs 28, +4(0), 1");
+	PAD_ORI
+}
+static void test_plfs_0_R1 (void) {
+  __asm__ __volatile__ ("plfs 28, +0(0), 1");
+	PAD_ORI
+}
+static void test_pstfd_32_R1 (void) {
+  __asm__ __volatile__ ("pstfd 26, -0x1f400+32(0), 1");
+}
+static void test_pstfd_16_R1 (void) {
+  __asm__ __volatile__ ("pstfd 26, -0x1f400+16(0), 1");
+}
+static void test_pstfd_8_R1 (void) {
+  __asm__ __volatile__ ("pstfd 26, -0x1f400+8(0), 1");
+}
+static void test_pstfd_4_R1 (void) {
+  __asm__ __volatile__ ("pstfd 26, -0x1f400+4(0), 1");
+}
+static void test_pstfd_0_R1 (void) {
+  __asm__ __volatile__ ("pstfd 26, -0x1f400+0(0), 1");
+}
+static void test_pstfs_32_R1 (void) {
+  __asm__ __volatile__ ("pstfs 26, -0x1f400+32(0), 1");
+}
+static void test_pstfs_16_R1 (void) {
+  __asm__ __volatile__ ("pstfs 26, -0x1f400+16(0), 1");
+}
+static void test_pstfs_8_R1 (void) {
+  __asm__ __volatile__ ("pstfs 26, -0x1f400+8(0), 1");
+}
+static void test_pstfs_4_R1 (void) {
+  __asm__ __volatile__ ("pstfs 26, -0x1f400+4(0), 1");
+}
+static void test_pstfs_0_R1 (void) {
+  __asm__ __volatile__ ("pstfs 26, -0x1f400+0(0), 1");
+}
+static void test_plxsd_64_R1 (void) {
+  __asm__ __volatile__ ("plxsd %0, +64(0), 1" : "=v" (vrt) );
+	PAD_ORI
+	PAD_ORI
+}
+static void test_plxsd_32_R1 (void) {
+  __asm__ __volatile__ (".align 2 ; plxsd %0, +32(0), 1" : "=v" (vrt) );
+	PAD_ORI
+}
+static void test_plxsd_16_R1 (void) {
+  __asm__ __volatile__ ("plxsd %0, +16(0), 1; pnop;pnop;pnop; " : "=v" (vrt) );
+	PAD_ORI
+}
+static void test_plxsd_8_R1 (void) {
+  __asm__ __volatile__ ("plxsd %0, +8(0), 1; pnop;pnop;pnop; " : "=v" (vrt) );
+	PAD_ORI
+}
+static void test_plxsd_4_R1 (void) {
+  __asm__ __volatile__ ("plxsd %0, +4(0), 1; pnop;pnop;pnop; "  : "=v" (vrt) );
+	PAD_ORI
+}
+static void test_plxsd_0_R1 (void) {
+  __asm__ __volatile__ ("plxsd %0, +0(0), 1; pnop;pnop;pnop; " : "=v" (vrt) );
+	PAD_ORI
+}
+static void test_plxssp_64_R1 (void) {
+  __asm__ __volatile__ ("plxssp %0, +64(0), 1; pnop;pnop;pnop; " : "=v" (vrt) );
+	PAD_ORI
+	PAD_ORI
+}
+static void test_plxssp_32_R1 (void) {
+  __asm__ __volatile__ ("plxssp %0, +32(0), 1; pnop; " : "=v" (vrt) );
+	PAD_ORI
+}
+static void test_plxssp_16_R1 (void) {
+  __asm__ __volatile__ ("plxssp %0, +16(0), 1; pnop;pnop;pnop; " : "=v" (vrt) );
+	PAD_ORI
+}
+static void test_plxssp_8_R1 (void) {
+  __asm__ __volatile__ ("plxssp %0, +8(0), 1; pnop;pnop;pnop; " : "=v" (vrt) );
+	PAD_ORI
+}
+static void test_plxssp_4_R1 (void) {
+  __asm__ __volatile__ ("plxssp %0, +4(0), 1; pnop;pnop;pnop; " : "=v" (vrt) );
+	PAD_ORI
+}
+static void test_plxssp_0_R1 (void) {
+  __asm__ __volatile__ ("plxssp %0, +0(0), 1; pnop;pnop;pnop; " : "=v" (vrt) );
+	PAD_ORI
+}
+/* Follow the short-range plxv instructions with nop in order to
+   pad out subsequent instructions.  When written there are found
+   to be fluctuations in the instructions to store the result back
+   into the target variable.  (pla,pstxv...).
+   */
+static void test_plxv_16_R1 (void) {
+  __asm__ __volatile__ ("plxv %x0, +16(0), 1; pnop;pnop;pnop;" : "=wa" (vec_xt) );
+	PAD_ORI
+}
+static void test_plxv_8_R1 (void) {
+  __asm__ __volatile__ ("plxv %x0, +8(0), 1; pnop;pnop;pnop;" : "=wa" (vec_xt) );
+	PAD_ORI
+}
+static void test_plxv_4_R1 (void) {
+  __asm__ __volatile__ ("plxv %x0, +4(0), 1; pnop;pnop;pnop;" : "=wa" (vec_xt) );
+	PAD_ORI
+}
+static void test_plxv_0_R1 (void) {
+  __asm__ __volatile__ ("plxv %x0, +0(0), 1; pnop;pnop;pnop; " : "=wa" (vec_xt) );
+	PAD_ORI
+}
+static void test_pstxsd_64_R1 (void) {
+  __asm__ __volatile__ (".align 2 ; pstxsd 22, -0x1f400+64(0), 1" );
+}
+static void test_pstxsd_32_R1 (void) {
+  __asm__ __volatile__ (".align 2 ; pstxsd 22, -0x1f400+32(0), 1" );
+}
+static void test_pstxsd_16_R1 (void) {
+  __asm__ __volatile__ (".align 2 ; pstxsd 22, -0x1f400+16(0), 1" );
+}
+static void test_pstxsd_8_R1 (void) {
+  __asm__ __volatile__ (".align 2 ; pstxsd 22, -0x1f400+8(0), 1" );
+}
+static void test_pstxsd_4_R1 (void) {
+  __asm__ __volatile__ (".align 2 ; pstxsd 22, -0x1f400+4(0), 1"  );
+}
+static void test_pstxsd_0_R1 (void) {
+  __asm__ __volatile__ (".align 2 ; pstxsd 22, -0x1f400+0(0), 1" );
+}
+static void test_pstxssp_64_R1 (void) {
+  __asm__ __volatile__ ("pstxssp 22, -0x1f400+64(0), 1" );
+}
+static void test_pstxssp_32_R1 (void) {
+  __asm__ __volatile__ ("pstxssp 22, -0x1f400+32(0), 1");
+}
+static void test_pstxssp_16_R1 (void) {
+  __asm__ __volatile__ ("pstxssp 22, -0x1f400+16(0), 1");
+}
+static void test_pstxssp_8_R1 (void) {
+  __asm__ __volatile__ ("pstxssp 22, -0x1f400+8(0), 1");
+}
+static void test_pstxssp_4_R1 (void) {
+  __asm__ __volatile__ ("pstxssp 22, -0x1f400+4(0), 1");
+}
+static void test_pstxssp_0_R1 (void) {
+  __asm__ __volatile__ ("pstxssp 22, -0x1f400+0(0), 1");
+}
+static void test_pstxv_16_R1 (void) {
+  __asm__ __volatile__ ("pstxv %x0, -0x1f400+16(0), 1" :: "wa" (vec_xs));
+}
+static void test_pstxv_8_R1 (void) {
+  __asm__ __volatile__ ("pstxv %x0, -0x1f400+8(0), 1" :: "wa" (vec_xs));
+}
+static void test_pstxv_4_R1 (void) {
+  __asm__ __volatile__ ("pstxv %x0, -0x1f400+4(0), 1" :: "wa" (vec_xs));
+}
+static void test_pstxv_0_R1 (void) {
+  __asm__ __volatile__ ("pstxv %x0, -0x1f400+0(0), 1" :: "wa" (vec_xs));
+}
+
+static test_list_t testgroup_generic[] = {
+  { &test_plfd_0_R1, "plfd 0_R1", "FRT,D(RA),R"}, /* bcwp */
+  { &test_plfd_4_R1, "plfd 4_R1", "FRT,D(RA),R"}, /* bcwp */
+  { &test_plfd_8_R1, "plfd 8_R1", "FRT,D(RA),R"}, /* bcwp */
+  { &test_plfd_16_R1, "plfd 16_R1", "FRT,D(RA),R"}, /* bcwp */
+  { &test_plfd_32_R1, "plfd 32_R1", "FRT,D(RA),R"}, /* bcwp */
+  { &test_plfd_64_R1, "plfd 64_R1", "FRT,D(RA),R"}, /* bcwp */
+  { &test_plfs_0_R1, "plfs 0_R1", "FRT,D(RA),R"}, /* bcwp */
+  { &test_plfs_4_R1, "plfs 4_R1", "FRT,D(RA),R"}, /* bcwp */
+  { &test_plfs_8_R1, "plfs 8_R1", "FRT,D(RA),R"}, /* bcwp */
+  { &test_plfs_16_R1, "plfs 16_R1", "FRT,D(RA),R"}, /* bcwp */
+  { &test_plfs_32_R1, "plfs 32_R1", "FRT,D(RA),R"}, /* bcwp */
+  { &test_plfs_64_R1, "plfs 64_R1", "FRT,D(RA),R"}, /* bcwp */
+  { &test_plxsd_0_R1, "plxsd 0_R1", "VRT,D(RA),R", 0b00110000}, /* bcwp */
+  { &test_plxsd_4_R1, "plxsd 4_R1", "VRT,D(RA),R", 0b00110000}, /* bcwp */
+  { &test_plxsd_8_R1, "plxsd 8_R1", "VRT,D(RA),R", 0b00110000}, /* bcwp */
+  { &test_plxsd_16_R1, "plxsd 16_R1", "VRT,D(RA),R", 0b00110000}, /* bcwp */
+  { &test_plxsd_32_R1, "plxsd 32_R1", "VRT,D(RA),R", 0b00110000}, /* bcwp */
+  { &test_plxsd_64_R1, "plxsd 64_R1", "VRT,D(RA),R", 0b00110000}, /* bcwp */
+  { &test_plxssp_0_R1, "plxssp 0_R1", "VRT,D(RA),R", 0b00001111}, /* bcwp */
+  { &test_plxssp_4_R1, "plxssp 4_R1", "VRT,D(RA),R", 0b00001111}, /* bcwp */
+  { &test_plxssp_8_R1, "plxssp 8_R1", "VRT,D(RA),R", 0b00001111}, /* bcwp */
+  { &test_plxssp_16_R1, "plxssp 16_R1", "VRT,D(RA),R", 0b00001111}, /* bcwp */
+  { &test_plxssp_32_R1, "plxssp 32_R1", "VRT,D(RA),R", 0b00001111}, /* bcwp */
+  { &test_plxssp_64_R1, "plxssp 64_R1", "VRT,D(RA),R", 0b00001111}, /* bcwp */
+  { &test_plxv_0_R1, "plxv 0_R1", "XT,D(RA),R"}, /* bcwp */
+  { &test_plxv_4_R1, "plxv 4_R1", "XT,D(RA),R"}, /* bcwp */
+  { &test_plxv_8_R1, "plxv 8_R1", "XT,D(RA),R"}, /* bcwp */
+  { &test_plxv_16_R1, "plxv 16_R1", "XT,D(RA),R"}, /* bcwp */
+  { &test_pstfd_0_R1, "pstfd 0_R1", "FRS,D(RA),R", 0b00110000}, /* bcwp */
+  { &test_pstfd_4_R1, "pstfd 4_R1", "FRS,D(RA),R", 0b00110000}, /* bcwp */
+  { &test_pstfd_8_R1, "pstfd 8_R1", "FRS,D(RA),R", 0b00110000}, /* bcwp */
+  { &test_pstfd_16_R1, "pstfd 16_R1", "FRS,D(RA),R", 0b00110000}, /* bcwp */
+  { &test_pstfd_32_R1, "pstfd 32_R1", "FRS,D(RA),R", 0b00110000}, /* bcwp */
+  { &test_pstfs_0_R1, "pstfs 0_R1", "FRS,D(RA),R", 0b00001111}, /* bcwp */
+  { &test_pstfs_4_R1, "pstfs 4_R1", "FRS,D(RA),R", 0b00001111}, /* bcwp */
+  { &test_pstfs_8_R1, "pstfs 8_R1", "FRS,D(RA),R", 0b00001111}, /* bcwp */
+  { &test_pstfs_16_R1, "pstfs 16_R1", "FRS,D(RA),R", 0b00001111}, /* bcwp */
+  { &test_pstfs_32_R1, "pstfs 32_R1", "FRS,D(RA),R", 0b00001111}, /* bcwp */
+  { &test_pstxsd_0_R1, "pstxsd 0_R1", "VRS,D(RA),R"}, /* bcwp */
+  { &test_pstxsd_4_R1, "pstxsd 4_R1", "VRS,D(RA),R"}, /* bcwp */
+  { &test_pstxsd_8_R1, "pstxsd 8_R1", "VRS,D(RA),R"}, /* bcwp */
+  { &test_pstxsd_16_R1, "pstxsd 16_R1", "VRS,D(RA),R"}, /* bcwp */
+  { &test_pstxsd_32_R1, "pstxsd 32_R1", "VRS,D(RA),R"}, /* bcwp */
+  { &test_pstxsd_64_R1, "pstxsd 64_R1", "VRS,D(RA),R"}, /* bcwp */
+  { &test_pstxssp_0_R1, "pstxssp 0_R1", "VRS,D(RA),R"}, /* bcwp */
+  { &test_pstxssp_4_R1, "pstxssp 4_R1", "VRS,D(RA),R"}, /* bcwp */
+  { &test_pstxssp_8_R1, "pstxssp 8_R1", "VRS,D(RA),R"}, /* bcwp */
+  { &test_pstxssp_16_R1, "pstxssp 16_R1", "VRS,D(RA),R"}, /* bcwp */
+  { &test_pstxssp_32_R1, "pstxssp 32_R1", "VRS,D(RA),R"}, /* bcwp */
+  { &test_pstxssp_64_R1, "pstxssp 64_R1", "VRS,D(RA),R"}, /* bcwp */
+  { &test_pstxvp_off0_R1, "pstxvp off0_R1", "XSp,D(RA),R"}, /* bcwp */
+  { &test_pstxvp_off16_R1, "pstxvp off16_R1", "XSp,D(RA),R"}, /* bcwp */
+  { &test_pstxvp_off32_R1, "pstxvp off32_R1", "XSp,D(RA),R"}, /* bcwp */
+  { &test_pstxvp_off48_R1, "pstxvp off48_R1", "XSp,D(RA),R"}, /* bcwp */
+  { &test_pstxv_0_R1, "pstxv 0_R1", "XS,D(RA),R"}, /* bcwp */
+  { &test_pstxv_4_R1, "pstxv 4_R1", "XS,D(RA),R"}, /* bcwp */
+  { &test_pstxv_8_R1, "pstxv 8_R1", "XS,D(RA),R"}, /* bcwp */
+  { &test_pstxv_16_R1, "pstxv 16_R1", "XS,D(RA),R"}, /* bcwp */
+	{ NULL, 	    NULL },
+};
+
+/*  Allow skipping of tests. */
+unsigned long test_count=0xffff;
+unsigned long skip_count=0;
+unsigned long setup_only=0;
+
+/*  Set up a setjmp/longjmp to gently handle our SIGILLs and SIGSEGVs.  */
+static jmp_buf mybuf;
+
+/* This (testfunction_generic) is meant to handle all of the instruction
+   variations.  The helpers set up the register and iterator values
+   as is appropriate for the instruction being tested.  */
+static void testfunction_generic (const char* instruction_name,
+				  test_func_t test_function,
+				  unsigned int ignore_flags,
+				  char * cur_form) {
+
+   identify_form_components (instruction_name , cur_form);
+   debug_show_form (instruction_name, cur_form);
+   set_up_iterators ();
+   debug_show_iter_ranges ();
+   initialize_buffer (0);
+   init_pcrelative_write_target ();
+   debug_dump_buffer ();
+
+   for (vrai = a_start; vrai < a_iters ; vrai+=a_inc) {
+      for (vrbi = b_start; vrbi < b_iters ; vrbi+=b_inc) {
+	 for (vrci = c_start; vrci < c_iters ; vrci+=c_inc) {
+	    for (vrmi = m_start; (vrmi < m_iters) ; vrmi+=m_inc) {
+		CHECK_OVERRIDES
+		debug_show_current_iteration ();
+		// Be sure to initialize the target registers first.
+		initialize_target_registers ();
+		initialize_source_registers ();
+		vec_xa[0]=0x1234;
+		vec_xa[1]=0x4567;
+		printf ("%s", instruction_name);
+		print_register_header ();
+		printf( " =>"); fflush (stdout);
+		if (!setup_only) {
+		  if (enable_setjmp) {
+		   if ( setjmp ( mybuf ) ) {
+		     printf("signal tripped. (FIXME)\n");
+		     continue;
+		   }
+		  }
+		  (*test_function) ();
+		}
+		print_register_footer ();
+		print_result_buffer ();
+		print_pcrelative_write_target ();
+		printf ("\n");
+	    }
+	 }
+      }
+   }
+}
+
+void mykillhandler ( int x ) { longjmp (mybuf, 1); }
+void mysegvhandler ( int x ) { longjmp (mybuf, 1); }
+
+static void do_tests ( void )
+{
+   int groupcount;
+   char * cur_form;
+   test_group_t group_function = &testfunction_generic;
+   test_list_t *tests = testgroup_generic;
+
+   struct sigaction kill_action, segv_action;
+   struct sigaction old_kill_action, old_segv_action;
+   if (enable_setjmp) {
+      kill_action.sa_handler = mykillhandler;
+      segv_action.sa_handler = mysegvhandler;
+      sigemptyset ( &kill_action.sa_mask );
+      sigemptyset ( &segv_action.sa_mask );
+      kill_action.sa_flags = SA_NODEFER;
+      segv_action.sa_flags = SA_NODEFER;
+      sigaction ( SIGILL, &kill_action, &old_kill_action);
+      sigaction ( SIGSEGV, &segv_action, &old_segv_action);
+   }
+
+   for (groupcount = 0; tests[groupcount].name != NULL; groupcount++) {
+	cur_form = strdup(tests[groupcount].form);
+	current_test = tests[groupcount];
+	identify_instruction_by_func_name (current_test.name);
+	if (groupcount < skip_count) continue;
+	if (verbose) printf("Test #%d ,", groupcount);
+	if (verbose > 1) printf(" instruction %s (v=%d)", current_test.name, verbose);
+	(*group_function) (current_test.name, current_test.func, 0, cur_form );
+	printf ("\n");
+	if (groupcount >= (skip_count+test_count)) break;
+   }
+   if (debug_show_labels) printf("\n");
+   printf ("All done. Tested %d different instruction groups\n", groupcount);
+}
+
+static void usage (void)
+{
+   fprintf(stderr,
+      "Usage: test_isa_XXX [OPTIONS]\n"
+      "\t-h: display this help and exit\n"
+      "\t-v: increase verbosity\n"
+      "\t-a <foo> : limit number of a-iterations to <foo>\n"
+      "\t-b <foo> : limit number of b-iterations to <foo>\n"
+      "\t-c <foo> : limit number of c-iterations to <foo>\n"
+      "\t-n <foo> : limit to this number of tests.\n"
+      "\t-r <foo>: run only test # <foo> \n"
+      "\t\n"
+      "\t-j :enable setjmp to recover from illegal insns. \n"
+      "\t-m :(dev only?) lock VRM value to zero.\n"
+      "\t-z :(dev only?) lock MC value to zero.\n"
+      "\t-p :(dev only?) disable prefix instructions\n"
+      "\t-s <foo>: skip <foo> tests \n"
+      "\t-c <foo>: stop after running <foo> # of tests \n"
+      "\t-f : Do the test setup but do not actually execute the test instruction. \n"
+   );
+}
+
+int main (int argc, char **argv)
+{
+   int c;
+   while ((c = getopt(argc, argv, "dhjvmpfzs:a:b:c:n:r:")) != -1) {
+      switch (c) {
+	 case 'h':
+	    usage();
+	    return 0;
+
+	 case 'v':
+	    verbose++;
+	    break;
+
+	 /* Options related to limiting the test iterations.  */
+	 case 'a':
+	    a_limit=atoi (optarg);
+	    printf ("limiting a-iters to %ld.\n", a_limit);
+	    break;
+	 case 'b':
+	    b_limit=atoi (optarg);
+	    printf ("limiting b-iters to %ld.\n", b_limit);
+	    break;
+	 case 'c':
+	    c_limit=atoi (optarg);
+	    printf ("limiting c-iters to %ld.\n", c_limit);
+	    break;
+	 case 'n': // run this number of tests.
+	    test_count=atoi (optarg);
+	    printf ("limiting to %ld tests\n", test_count);
+	    break;
+	 case 'r': // run just test #<foo>.
+	    skip_count=atoi (optarg);
+	    test_count=0;
+	    if (verbose) printf("Running test number %ld\n", skip_count);
+	    break;
+	 case 's': // skip this number of tests.
+	    skip_count=atoi (optarg);
+	    printf ("skipping %ld tests\n", skip_count);
+	    break;
+
+	 /* debug options.  */
+	 case 'd':
+	    dump_tables=1;
+	    printf("DEBUG:dump_tables.\n");
+	    break;
+	 case 'f':
+	    setup_only=1;
+	    printf("DEBUG:setup_only.\n");
+	    break;
+	 case 'j':
+	    enable_setjmp=1;
+	    printf ("DEBUG:setjmp enabled.\n");
+	    break;
+	 case 'm':
+	    vrm_override=1;
+	    printf ("DEBUG:vrm override enabled.\n");
+	    break;
+	 case 'p':
+	    prefix_override=1;
+	    printf ("DEBUG:prefix override enabled.\n");
+	    break;
+	 case 'z':
+	    mc_override=1;
+	    printf ("DEBUG:MC override enabled.\n");
+	    break;
+	 default:
+	    usage();
+	    fprintf(stderr, "Unknown argument: '%c'\n", c);
+	   }
+	}
+
+	generic_prologue ();
+	build_vsx_table ();
+	build_args_table ();
+	build_float_vsx_tables ();
+
+	if (dump_tables) {
+	   dump_float_vsx_tables ();
+	   dump_vsxargs ();
+	}
+
+	do_tests ();
+
+	return 0;
+}
+
+#else	   // HAS_ISA_3_1
+int main (int argc, char **argv)
+{
+   printf("NO ISA 3.1 SUPPORT\n");
+   return 0;
+}
+#endif
diff --git a/none/tests/ppc64/test_isa_3_1_R1_XT.stderr.exp b/none/tests/ppc64/test_isa_3_1_R1_XT.stderr.exp
new file mode 100644
index 000000000..139597f9c
--- /dev/null
+++ b/none/tests/ppc64/test_isa_3_1_R1_XT.stderr.exp
@@ -0,0 +1,2 @@
+
+
diff --git a/none/tests/ppc64/test_isa_3_1_R1_XT.stdout.exp b/none/tests/ppc64/test_isa_3_1_R1_XT.stdout.exp
new file mode 100644
index 000000000..48d591f4d
--- /dev/null
+++ b/none/tests/ppc64/test_isa_3_1_R1_XT.stdout.exp
@@ -0,0 +1,127 @@
+plfd 0_R1 =>_ -4.903986e+55 _  cb80000006100000, 0 
+
+plfd 4_R1 =>_ 3.095878e+167 _  62b50015cb800004, 0 
+
+plfd 8_R1 =>_ 1.297320e+168 _  62d6001662b50015, 0 
+
+plfd 16_R1 =>_ 2.264413e+169 _  6318001862f70017, 0 
+
+plfd 32_R1 =>_ 6.763045e+171 _  639c001c637b001b, 0 
+
+plfd 64_R1 =>_ 6.763045e+171 _  639c001c637b001b, 0 
+
+plfs 0_R1 =>_ 2.708339e-35 _  38c2000000000000, 0 
+
+plfs 4_R1 =>_ -2.560001e+02 _  c070000080000000, 0 
+
+plfs 8_R1 =>_ 1.669433e+21 _  4456a002a0000000, 0 
+
+plfs 16_R1 =>_ 2.278176e+21 _  445ee002e0000000, 0 
+
+plfs 32_R1 =>_ 4.630140e+21 _  446f600360000000, 0 
+
+plfs 64_R1 =>_ 4.630140e+21 _  446f600360000000, 0 
+
+plxsd 0_R1 => a800000004100000,0000000000000000 -5.07588375e-116            +Zero
+
+plxsd 4_R1 =>  7000000a8000004,0000000000000000  5.77662562e-275            +Zero
+
+plxsd 8_R1 =>  700000060000000,0000000000000000  5.77662407e-275            +Zero
+
+plxsd 16_R1 =>          7000000,0000000000000000             +Den            +Zero
+
+plxsd 32_R1 => 6339001963180018,0000000000000000  9.43505226e+169            +Zero
+
+plxsd 64_R1 => 6339001963180018,0000000000000000  9.43505226e+169            +Zero
+
+plxssp 0_R1 => 3882000000000000,0000000000000000     6.19888e-05           +Zero           +Zero           +Zero
+
+plxssp 4_R1 => bd80000080000000,0000000000000000    -6.25000e-02           -Zero           +Zero           +Zero
+
+plxssp 8_R1 => 38e0000000000000,0000000000000000     1.06812e-04           +Zero           +Zero           +Zero
+
+plxssp 16_R1 => 38e0000000000000,0000000000000000     1.06812e-04           +Zero           +Zero           +Zero
+
+plxssp 32_R1 => 445ac002c0000000,0000000000000000     8.75000e+02    -2.00000e+00           +Zero           +Zero
+
+plxssp 64_R1 => 446b400340000000,0000000000000000     9.41000e+02     2.00000e+00           +Zero           +Zero
+
+plxv 0_R1 => c800000004100000          7000000
+
+plxv 4_R1 =>  7000000c8000004  700000000000000
+
+plxv 8_R1 =>          7000000          7000000
+
+plxv 16_R1 =>          7000000          7000000
+
+pstfd 0_R1 43dfe000003fe000 43eff000000ff000 => e000003fe00043df
+pstfd 0_R1 43eff000000ff000 43efefffffcff000 => f000000ff00043ef
+
+pstfd 4_R1 43dfe000003fe000 43eff000000ff000 =>     e000003f e00043df    
+pstfd 4_R1 43eff000000ff000 43efefffffcff000 =>     f000000f f00043ef    
+
+pstfd 8_R1 43dfe000003fe000 43eff000000ff000 => e000003fe00043df
+pstfd 8_R1 43eff000000ff000 43efefffffcff000 => f000000ff00043ef
+
+pstfd 16_R1 43dfe000003fe000 43eff000000ff000 => e000003fe00043df
+pstfd 16_R1 43eff000000ff000 43efefffffcff000 => f000000ff00043ef
+
+pstfd 32_R1 43dfe000003fe000 43eff000000ff000 => e000003fe00043df
+pstfd 32_R1 43eff000000ff000 43efefffffcff000 => f000000ff00043ef
+
+pstfs 0_R1 000000005eff0000 000000005f7f8000 => 00005eff    
+pstfs 0_R1 000000005f7f8000 000000005f7f8000 => 80005f7f    
+
+pstfs 4_R1 000000005eff0000 000000005f7f8000 =>     00005eff
+pstfs 4_R1 000000005f7f8000 000000005f7f8000 =>     80005f7f
+
+pstfs 8_R1 000000005eff0000 000000005f7f8000 => 00005eff    
+pstfs 8_R1 000000005f7f8000 000000005f7f8000 => 80005f7f    
+
+pstfs 16_R1 000000005eff0000 000000005f7f8000 => 00005eff    
+pstfs 16_R1 000000005f7f8000 000000005f7f8000 => 80005f7f    
+
+pstfs 32_R1 000000005eff0000 000000005f7f8000 => 00005eff    
+pstfs 32_R1 000000005f7f8000 000000005f7f8000 => 80005f7f    
+
+pstxsd 0_R1 => 0000000000000000
+
+pstxsd 4_R1 =>     00000000 00000000    
+
+pstxsd 8_R1 => 0000000000000000
+
+pstxsd 16_R1 => 0000000000000000
+
+pstxsd 32_R1 => 0000000000000000
+
+pstxsd 64_R1 => 0000000000000000
+
+pstxssp 0_R1 => 00000000    
+
+pstxssp 4_R1 =>     00000000
+
+pstxssp 8_R1 => 00000000    
+
+pstxssp 16_R1 => 00000000    
+
+pstxssp 32_R1 => 00000000    
+
+pstxssp 64_R1 => 00000000    
+
+pstxvp off0_R1 0180055e0180077e 0080000e8080000e ff7ffffe7f7ffffe ff8000007f800000 => fffe7f7ffffeff7f 00007f800000ff80 077e0180055e0180 000e8080000e0080
+
+pstxvp off16_R1 0180055e0180077e 0080000e8080000e ff7ffffe7f7ffffe ff8000007f800000 => fffe7f7ffffeff7f 00007f800000ff80 077e0180055e0180 000e8080000e0080
+
+pstxvp off32_R1 0180055e0180077e 0080000e8080000e ff7ffffe7f7ffffe ff8000007f800000 => fffe7f7ffffeff7f 00007f800000ff80 077e0180055e0180 000e8080000e0080
+
+pstxvp off48_R1 0180055e0180077e 0080000e8080000e ff7ffffe7f7ffffe ff8000007f800000 => fffe7f7ffffeff7f 00007f800000ff80 077e0180055e0180 000e8080000e0080
+
+pstxv 0_R1 ff7ffffe7f7ffffe,ff8000007f800000 => fffe7f7ffffeff7f 00007f800000ff80
+
+pstxv 4_R1 ff7ffffe7f7ffffe,ff8000007f800000 => fffe7f7ffffeff7f 00007f800000ff80
+
+pstxv 8_R1 ff7ffffe7f7ffffe,ff8000007f800000 => fffe7f7ffffeff7f 00007f800000ff80
+
+pstxv 16_R1 ff7ffffe7f7ffffe,ff8000007f800000 =>     fffe7f7f fffeff7f00007f80 0000ff80    
+
+All done. Tested 58 different instruction groups
diff --git a/none/tests/ppc64/test_isa_3_1_R1_XT.vgtest b/none/tests/ppc64/test_isa_3_1_R1_XT.vgtest
new file mode 100644
index 000000000..7331aafad
--- /dev/null
+++ b/none/tests/ppc64/test_isa_3_1_R1_XT.vgtest
@@ -0,0 +1,2 @@
+prereq: ../../../tests/check_ppc64_auxv_cap arch_3_1
+prog: test_isa_3_1_R1_XT
diff --git a/none/tests/ppc64/test_isa_3_1_common.c b/none/tests/ppc64/test_isa_3_1_common.c
index 7c3dc6f00..b3320277b 100644
--- a/none/tests/ppc64/test_isa_3_1_common.c
+++ b/none/tests/ppc64/test_isa_3_1_common.c
@@ -134,11 +134,13 @@ bool uses_acc_vsrs;
 bool uses_pmsk;
 bool uses_buffer;  // Buffer related.
 bool uses_load_buffer, uses_store_buffer, uses_any_buffer;
+bool updates_byte, updates_halfword, updates_word; // output helpers.
 bool uses_quad;
 unsigned long output_mask;  // Output field special handling.
 bool instruction_is_sp, instruction_is_sp_estimate;
 bool instruction_is_dp, instruction_is_dp_estimate;
 bool instruction_is_b16;
+bool instruction_is_relative;
 
 unsigned long long min (unsigned long long a, unsigned long long b) {
    if ( a < b )
@@ -236,6 +238,18 @@ void identify_form_components (const char *instruction_name,
       (strncmp (instruction_name, "pmst", 4) == 0) ||
       (strncmp (instruction_name, "pst", 3) == 0) ||
       (strncmp (instruction_name, "st", 2) == 0));
+   updates_byte = (
+      (strncmp (instruction_name, "pstb", 4) == 0) );
+   updates_halfword = (
+      (strncmp (instruction_name, "psth", 4) == 0) ||
+       (strncmp (instruction_name, "pstfs", 4) == 0) ||
+       (strncmp (instruction_name, "pstxsd", 4) == 0) ||
+       (strncmp (instruction_name, "pstxssp", 4) == 0) ||
+       (strncmp (instruction_name, "pstxv", 4) == 0) ||
+       (strncmp (instruction_name, "psfs", 4) == 0) );
+   updates_word = (
+      (strncmp (instruction_name, "pstw", 4) == 0) );
+
    uses_any_buffer = (strstr (cur_form, "(RA)") != NULL);
    uses_buffer = uses_any_buffer||uses_load_buffer||uses_store_buffer;
 
@@ -268,6 +282,15 @@ void identify_form_components (const char *instruction_name,
    instruction_is_b16 =         ( current_test.mask & B16_MASK        );
 }
 
+/* Parse the provided function name to set assorted values.
+   In particular, set an indicator when the instruction test has
+   indicated it will run with R==1 that indicates it is a PC-relative
+   instruction.  Those tests should all have "_R1" as part of
+   the function name.  */
+void identify_instruction_by_func_name(const char * function_name) {
+   instruction_is_relative = ( (strstr (function_name, "R1") != NULL));
+}
+
 void display_form_components (char * cur_form) {
    printf (" %s\n", cur_form);
    printf ("Instruction form elements: ");
@@ -288,7 +311,7 @@ void display_form_components (char * cur_form) {
    if (has_frbp) printf ("frbp ");
    if (has_frs)  printf ("frs ");
    if (has_frsp) printf ("frsp ");
-   if (has_frt)  printf ("frt ");
+   if (has_frt)  printf ("frt%s ",(instruction_is_relative)?"-raw":"");
    if (has_frtp) printf ("frtp ");
    if (has_xa)   printf ("xa ");
    if (has_xap)  printf ("xap ");
@@ -298,6 +321,7 @@ void display_form_components (char * cur_form) {
    if (has_xsp)  printf ("xsp ");
    if (has_xt)   printf ("xt ");
    if (has_xtp)  printf ("xtp ");
+   if (instruction_is_relative)  printf ("R==1 ");
    if (uses_acc_src) printf ("AS ");
    if (uses_acc_dest) printf ("AT ");
    printf ("\n");
@@ -991,6 +1015,107 @@ if (debug_show_values) printf (" buffer:");
   }
 }
 
+/* **** Reloc Buffer **************************************** */
+/* Create a large buffer to be the destination for pc-relative
+ * writes.  This test is built with linker hints in order
+ * to ensure our buffer, stored in the .bss section, is at a
+ * mostly known offset from the instructions being exercised,
+ * so a hardcoded offset from the PC (pc-relative) will be
+ * on-target.
+ * If there are significant reworks to the code, the bss or
+ * text sections, or the offsets used may need to change.
+ *
+ * The linker hints are specifically -Tbss and -Ttext.
+ * gcc foo.c test_isa_3_1_common.c -I../../../   -Wl,-Tbss 0x20000 -Wl,-Ttext 0x40000
+ */
+ /* RELOC_BUFFER_SIZE is defined to 0x1000 in isa_3_1_helpers.h  */
+#define RELOC_BUFFER_PATTERN 0x0001000100010001
+volatile unsigned long long pcrelative_write_target[RELOC_BUFFER_SIZE];
+
+/* Initialize the buffer to known values. */
+void init_pcrelative_write_target() {
+       int i;
+       for (i=0;i<RELOC_BUFFER_SIZE;i++)
+               pcrelative_write_target[i]=i*RELOC_BUFFER_PATTERN;
+}
+
+/* Review the pcrelative_write_target buffer; and print any
+   elements that vary from the initialized value.
+   Exclude portions of the output as appropriate if the current test
+   is marked for byte,halfword,word.  */
+void print_pcrelative_write_target() {
+  int i,z,rshift;
+  unsigned long long curr_value;
+  unsigned long long ref_value;
+  unsigned long long curr_token,init_token;
+  for (i=0;i<RELOC_BUFFER_SIZE;i++) {
+    ref_value=i*RELOC_BUFFER_PATTERN;
+    curr_value = pcrelative_write_target[i];
+    if (ref_value != curr_value) {
+      printf(" ");
+      if (verbose)
+	printf("delta found: %d %llx -> %llx\n",i,ref_value,curr_value);
+      if (updates_byte) {
+	for (z=0;z<8;z++) {
+	  rshift=z*8;
+	  if (verbose) printf("z:%d ",z);
+	  init_token = (ref_value>>rshift) & 0xff;
+	  curr_token = (curr_value>>rshift) & 0xff;
+	  if (verbose)
+	    printf("wms byte:: %llx -> %llx \n",init_token,curr_token);
+	  if (init_token == curr_token && (updates_byte||updates_halfword||updates_word) ) {
+	     printf("%2s","  ");
+	  } else {
+	    printf("%02llx",curr_token);
+	  }
+        }
+      }
+      else if (updates_halfword) {
+	for (z=0;z<4;z++) {
+	  rshift=z*16;
+	  if (verbose) printf("z:%d ",z);
+	  init_token = (ref_value>>rshift) & 0xffff;
+	  curr_token = (curr_value>>rshift) & 0xffff;
+	  if (verbose)
+	    printf("wms half:: %llx -> %llx \n",init_token,curr_token);
+	  if (init_token == curr_token) {
+	     printf("%2s","  ");
+	  } else {
+	    printf("%04llx",curr_token);
+	  }
+        }
+      }
+      else if (updates_word) {
+	for (z=0;z<2;z++) {
+	  rshift=z*32;
+	  if (verbose) printf("z:%d ",z);
+	  init_token = (ref_value>>rshift) & 0xffffffff;
+	  curr_token = (curr_value>>rshift) & 0xffffffff;
+	  if (verbose)
+	    printf("wms word:: %llx -> %llx \n",init_token,curr_token);
+	  if (init_token == curr_token ) {
+	     printf("%2s","  ");
+	  } else {
+	    printf("%08llx",curr_token);
+	  }
+        }
+      }
+      else {
+	printf("%016llx ",curr_value);
+      }
+    }
+  }
+}
+
+/* Helper that returns the address of the pcrelative_write_target buffer.
+   Due to variances in where the sections land in memory, this value is
+   used to normalize the results.  (see paddi tests for usage).   */
+unsigned long long pcrelative_buff_addr(int x) {
+   /* Return the base address of the array.  The base address will be
+      a function of the code load address.  */
+   return (unsigned long long) &pcrelative_write_target[x];
+}
+
 void print_undefined () {
    if (debug_show_values)
       printf (" [Undef]");
@@ -1339,7 +1464,7 @@ void print_frt () {
       /* If the result is a dfp128 value, the dfp128 value is
          contained in the frt, frtp values which are split across
          a pair of VSRs.  */
-      if (uses_dfp128_output) {
+      if (!instruction_is_relative && uses_dfp128_output) {
 	 if (verbose) print_vsr (28);
 	 if (verbose) print_vsr (29);
 	 value1 = get_vsrhd_vs28 ();
@@ -1347,7 +1472,12 @@ void print_frt () {
 	 dissect_dfp128_float (value1, value3);
       } else {
 	 if (debug_show_raw_values) generic_print_float_as_hex (frt);
-	 printf (" %e", frt);
+	 if (instruction_is_relative) {
+	    printf ("_ %e _ ", frt);
+	    print_vsr (28);
+	 } else {
+		printf (" %e", frt);
+	  }
 	 if (has_frtp) {
 	    if (debug_show_raw_values) generic_print_float_as_hex (frtp);
 	    printf (" %e", frtp);
@@ -1652,7 +1782,15 @@ void print_all() {
 void print_register_header () {
   post_test = 0;
   if (debug_show_all_regs) print_all();
-  if (has_ra) print_ra ();
+
+  if (has_ra) {
+	  /* Suppress the print of RA if the instruction has
+	     R==1, since the ra value must be zero for the
+	     instruction to be valid.  */
+	  if (!instruction_is_relative)
+		 print_ra();
+  }
+
   if (has_rb) print_rb ();
   if (has_rc) print_rc ();
   if (has_rs) print_rs();
@@ -1894,6 +2032,11 @@ void set_up_iterators () {
    } else {
 	   a_start=0; b_start=0; c_start=0; m_start=0;
    }
+   /* Special casing for R==1 tests. */
+   if (instruction_is_relative) {
+	  a_iters = 1;
+	  m_start=3; m_iters=4;
+   }
    if ((has_vra+has_vrb+has_vrc+has_vrm+has_xa+has_xb+uses_MC > 2) &&
        (!debug_enable_all_iters)) {
       /* Instruction tests using multiple fields will generate a lot of
@@ -2196,15 +2339,12 @@ void initialize_source_registers () {
 	  vrb[0] = vsxargs[ (vrbi  ) % isr_modulo];
 	  vrb[1] = vsxargs[ (vrbi+1) % isr_modulo];
    }
- 
-  if (has_xa) { 
-    vec_xa[0] = vsxargs[ (vrai  ) % isr_modulo];
-    vec_xa[1] = vsxargs[ (vrai+1) % isr_modulo];
-  }
-  if (has_xb) {
-    vec_xb[0] = vsxargs[ (vrbi  ) % isr_modulo];
-    vec_xb[1] = vsxargs[ (vrbi+1) % isr_modulo];
-  }
+
+   if (instruction_is_relative) {
+     /* for pstxsd and friends using R=1 */
+     vec_xa[0] = vsxargs[ (vrai+2  ) % isr_modulo];
+     vec_xa[1] = vsxargs[ (vrai+3  ) % isr_modulo];
+   }
 
    // xap 'shares' with the second half of an xa-pair.
   if (has_xap ) {