444495 dhat/tests/copy fails on s390x
444571 PPC, fix the lxsibzx and lxsihzx so they only load their respective
sized data.
+444836 PPC, pstq instruction for R=1 is not storing to the correct address.
To see details of a given bug, visit
https://bugs.kde.org/show_bug.cgi?id=XXXXXX
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 \
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 \
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
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
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)
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();
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)
--- /dev/null
+/*
+ * 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
--- /dev/null
+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
--- /dev/null
+prereq: ../../../tests/check_ppc64_auxv_cap arch_3_1
+prog: test_isa_3_1_R1_RT
--- /dev/null
+/*
+ * 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
--- /dev/null
+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
--- /dev/null
+prereq: ../../../tests/check_ppc64_auxv_cap arch_3_1
+prog: test_isa_3_1_R1_XT
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 )
(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;
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: ");
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 ");
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");
}
}
+/* **** 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]");
/* 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 ();
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);
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();
} 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
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 ) {