diff --git a/NEWS b/NEWS index 9a49fd060..888f07bb6 100644 --- a/NEWS +++ b/NEWS @@ -45,6 +45,7 @@ are not entered into bugzilla tend to get forgotten about or ignored. 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 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 ) {