From 1cb064e6af74fd5a83a449d2fbdf72a753ef7bd1 Mon Sep 17 00:00:00 2001 From: Mark Wielaard Date: Nov 17 2021 15:27:15 +0000 Subject: Add valgrind-3.18.1-ppc-pstq-tests.patch --- diff --git a/valgrind-3.18.1-ppc-pstq-tests.patch b/valgrind-3.18.1-ppc-pstq-tests.patch new file mode 100644 index 0000000..58498f2 --- /dev/null +++ b/valgrind-3.18.1-ppc-pstq-tests.patch @@ -0,0 +1,1876 @@ +commit 3950c5d661ee09526cddcf24daf5fc22bc83f70c +Author: Carl Love +Date: Mon Nov 1 11:18:32 2021 -0500 + + Valgrind Add powerpc R=1 tests + + Contributed by Will Schmidt + + 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 ++ * ++ * 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 ++#ifdef HAS_ISA_3_1 ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++ ++/* 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 : limit number of a-iterations to \n" ++ "\t-b : limit number of b-iterations to \n" ++ "\t-c : limit number of c-iterations to \n" ++ "\t-n : limit to this number of tests.\n" ++ "\t-r : run only test # \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 : skip tests \n" ++ "\t-c : stop after running # 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 #. ++ 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 ++ * ++ * 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 ++#ifdef HAS_ISA_3_1 ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++ ++/* 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 : limit number of a-iterations to \n" ++ "\t-b : limit number of b-iterations to \n" ++ "\t-c : limit number of c-iterations to \n" ++ "\t-n : limit to this number of tests.\n" ++ "\t-r : run only test # \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 : skip tests \n" ++ "\t-c : stop after running # 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 #. ++ 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 %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 ) { diff --git a/valgrind.spec b/valgrind.spec index a9f0e5e..f140424 100644 --- a/valgrind.spec +++ b/valgrind.spec @@ -95,8 +95,11 @@ Patch7: valgrind-3.18.1-s390x-EXRL.patch Patch8: valgrind-3.18.1-ppc64-lxsibzx-lxsihzx.patch # commit ae8c6de01417023e78763de145b1c0e6ddd87277 +# commit 3950c5d661ee09526cddcf24daf5fc22bc83f70c # Fix for the prefixed stq instruction in PC relative mode. +# KDE#444836 pstq instruction for R=1 is not storing to the correct address Patch9: valgrind-3.18.1-ppc-pstq.patch +Patch10: valgrind-3.18.1-ppc-pstq-tests.patch BuildRequires: make BuildRequires: glibc-devel @@ -239,6 +242,7 @@ Valgrind User Manual for details. %patch7 -p1 %patch8 -p1 %patch9 -p1 +%patch10 -p1 %build # LTO triggers undefined symbols in valgrind. Valgrind has a --enable-lto @@ -470,6 +474,7 @@ fi %changelog * Wed Nov 17 2021 Mark Wielaard - Add valgrind-3.18.1-ppc-pstq.patch +- Add valgrind-3.18.1-ppc-pstq-tests.patch * Mon Nov 1 2021 Mark Wielaard - 3.18.1-2 - Add valgrind-3.18.1-dhat-tests-copy.patch