valgrind svn commit r13494, VEX svn commit r2750 Initial ISA 2.07 support for POWER8-tuned libc The IBM Power ISA 2.07 has been published on power.org, and IBM's new POWER8 processor is under development to implement that ISA. This patch provides initial VEX support for running Valgrind on POWER8 systems running a soon-to-be released Linux distribution. This Linux distro will include a POWER8-tuned libc that uses a subset of the new instructions from ISA 2.07. Since virtually all applications link with libc, it would be impossible to run an application under Valgrind on this distro without adding support for these new instructions to Valgrind, so that's the intent of this patch. Note that applications built on this distro will *not* employ new POWER8 instructions by default. There are roughly 150 new instructions in the Power ISA 2.07, including hardware transaction management (HTM). Support for these new instructions (modulo the subset included in this bug) will be added to Valgrind in a phased approach, similar to what we did for Power ISA 2.06. Bugzilla 322294 diff -ur valgrind-3.8.1.orig/configure valgrind-3.8.1/configure --- valgrind-3.8.1.orig/configure 2013-08-13 13:07:12.837887980 +0200 +++ valgrind-3.8.1/configure 2013-08-13 13:28:33.188030564 +0200 @@ -673,6 +673,8 @@ FLAG_MMMX FLAG_M64 FLAG_M32 +HAS_ISA_2_07_FALSE +HAS_ISA_2_07_TRUE HAVE_PTHREAD_CREATE_GLIBC_2_0_FALSE HAVE_PTHREAD_CREATE_GLIBC_2_0_TRUE HAS_DFP_FALSE @@ -7321,6 +7323,47 @@ rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext +# isa 2.07 checking +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking that assembler knows ISA 2.07 " >&5 +$as_echo_n "checking that assembler knows ISA 2.07 ... " >&6; } + +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + +int +main () +{ + + __asm__ __volatile__("mtvsrd 1,2 "); + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + +ac_asm_have_isa_2_07=yes +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + +else + +ac_asm_have_isa_2_07=no +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + + if test x$ac_asm_have_isa_2_07 = xyes; then + HAS_ISA_2_07_TRUE= + HAS_ISA_2_07_FALSE='#' +else + HAS_ISA_2_07_TRUE='#' + HAS_ISA_2_07_FALSE= +fi + #---------------------------------------------------------------------------- # Checking for supported compiler flags. @@ -10411,6 +10454,10 @@ as_fn_error "conditional \"HAVE_PTHREAD_CREATE_GLIBC_2_0\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi +if test -z "${HAS_ISA_2_07_TRUE}" && test -z "${HAS_ISA_2_07_FALSE}"; then + as_fn_error "conditional \"HAS_ISA_2_07\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi if test -z "${DWARF4_TRUE}" && test -z "${DWARF4_FALSE}"; then as_fn_error "conditional \"DWARF4\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 diff -ur valgrind-3.8.1.orig/configure.in valgrind-3.8.1/configure.in --- valgrind-3.8.1.orig/configure.in 2013-08-13 13:07:12.800887713 +0200 +++ valgrind-3.8.1/configure.in 2013-08-13 13:10:17.485219043 +0200 @@ -1303,6 +1303,21 @@ AC_MSG_RESULT([no]) ]) +# isa 2.07 checking +AC_MSG_CHECKING([that assembler knows ISA 2.07 ]) + +AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ +]], [[ + __asm__ __volatile__("mtvsrd 1,2 "); +]])], [ +ac_asm_have_isa_2_07=yes +AC_MSG_RESULT([yes]) +], [ +ac_asm_have_isa_2_07=no +AC_MSG_RESULT([no]) +]) + +AM_CONDITIONAL(HAS_ISA_2_07, test x$ac_asm_have_isa_2_07 = xyes) #---------------------------------------------------------------------------- # Checking for supported compiler flags. diff -ur valgrind-3.8.1.orig/coregrind/m_machine.c valgrind-3.8.1/coregrind/m_machine.c --- valgrind-3.8.1.orig/coregrind/m_machine.c 2013-08-13 13:07:12.780887570 +0200 +++ valgrind-3.8.1/coregrind/m_machine.c 2013-08-13 13:10:17.487219057 +0200 @@ -862,6 +862,7 @@ vki_sigaction_toK_t tmp_sigill_act, tmp_sigfpe_act; volatile Bool have_F, have_V, have_FX, have_GX, have_VX, have_DFP; + volatile Bool have_isa_2_07; Int r; /* This is a kludge. Really we ought to back-convert saved_act @@ -956,6 +957,14 @@ __asm__ __volatile__(".long 0xee4e8005"); /* dadd FRT,FRA, FRB */ } + /* Check for ISA 2.07 support. */ + have_isa_2_07 = True; + if (VG_MINIMAL_SETJMP(env_unsup_insn)) { + have_isa_2_07 = False; + } else { + __asm__ __volatile__(".long 0x7c000166"); /* mtvsrd XT,RA */ + } + /* determine dcbz/dcbzl sizes while we still have the signal * handlers registered */ find_ppc_dcbz_sz(&vai); @@ -966,9 +975,10 @@ vg_assert(r == 0); r = VG_(sigprocmask)(VKI_SIG_SETMASK, &saved_set, NULL); vg_assert(r == 0); - VG_(debugLog)(1, "machine", "F %d V %d FX %d GX %d VX %d DFP %d\n", + VG_(debugLog)(1, "machine", "F %d V %d FX %d GX %d VX %d DFP %d ISA2.07 %d\n", (Int)have_F, (Int)have_V, (Int)have_FX, - (Int)have_GX, (Int)have_VX, (Int)have_DFP); + (Int)have_GX, (Int)have_VX, (Int)have_DFP, + (Int)have_isa_2_07); /* Make FP a prerequisite for VMX (bogusly so), and for FX and GX. */ if (have_V && !have_F) have_V = False; @@ -989,6 +999,7 @@ if (have_GX) vai.hwcaps |= VEX_HWCAPS_PPC32_GX; if (have_VX) vai.hwcaps |= VEX_HWCAPS_PPC32_VX; if (have_DFP) vai.hwcaps |= VEX_HWCAPS_PPC32_DFP; + if (have_isa_2_07) vai.hwcaps |= VEX_HWCAPS_PPC32_ISA2_07; /* But we're not done yet: VG_(machine_ppc32_set_clszB) must be @@ -1004,6 +1015,7 @@ vki_sigaction_toK_t tmp_sigill_act, tmp_sigfpe_act; volatile Bool have_F, have_V, have_FX, have_GX, have_VX, have_DFP; + volatile Bool have_isa_2_07; Int r; /* This is a kludge. Really we ought to back-convert saved_act @@ -1090,6 +1102,14 @@ __asm__ __volatile__(".long 0xee4e8005"); /* dadd FRT,FRA, FRB */ } + /* Check for ISA 2.07 support. */ + have_isa_2_07 = True; + if (VG_MINIMAL_SETJMP(env_unsup_insn)) { + have_isa_2_07 = False; + } else { + __asm__ __volatile__(".long 0x7c000166"); /* mtvsrd XT,RA */ + } + /* determine dcbz/dcbzl sizes while we still have the signal * handlers registered */ find_ppc_dcbz_sz(&vai); @@ -1097,9 +1117,10 @@ VG_(sigaction)(VKI_SIGILL, &saved_sigill_act, NULL); VG_(sigaction)(VKI_SIGFPE, &saved_sigfpe_act, NULL); VG_(sigprocmask)(VKI_SIG_SETMASK, &saved_set, NULL); - VG_(debugLog)(1, "machine", "F %d V %d FX %d GX %d VX %d DFP %d\n", + VG_(debugLog)(1, "machine", "F %d V %d FX %d GX %d VX %d DFP %d ISA2.07 %d\n", (Int)have_F, (Int)have_V, (Int)have_FX, - (Int)have_GX, (Int)have_VX, (Int)have_DFP); + (Int)have_GX, (Int)have_VX, (Int)have_DFP, + (Int)have_isa_2_07); /* on ppc64, if we don't even have FP, just give up. */ if (!have_F) return False; @@ -1114,6 +1135,7 @@ if (have_GX) vai.hwcaps |= VEX_HWCAPS_PPC64_GX; if (have_VX) vai.hwcaps |= VEX_HWCAPS_PPC64_VX; if (have_DFP) vai.hwcaps |= VEX_HWCAPS_PPC64_DFP; + if (have_isa_2_07) vai.hwcaps |= VEX_HWCAPS_PPC64_ISA2_07; /* But we're not done yet: VG_(machine_ppc64_set_clszB) must be called before we're ready to go. */ diff -ur valgrind-3.8.1.orig/memcheck/mc_translate.c valgrind-3.8.1/memcheck/mc_translate.c --- valgrind-3.8.1.orig/memcheck/mc_translate.c 2013-08-13 13:07:12.733887229 +0200 +++ valgrind-3.8.1/memcheck/mc_translate.c 2013-08-13 13:10:17.490219078 +0200 @@ -3223,6 +3223,7 @@ than a data steering operation. */ case Iop_NarrowBin32to16x8: case Iop_NarrowBin16to8x16: + case Iop_NarrowBin64to32x4: return assignNew('V', mce, Ity_V128, binop(op, vatom1, vatom2)); diff -ur valgrind-3.8.1.orig/none/tests/ppc32/Makefile.am valgrind-3.8.1/none/tests/ppc32/Makefile.am --- valgrind-3.8.1.orig/none/tests/ppc32/Makefile.am 2013-08-13 13:07:12.633886508 +0200 +++ valgrind-3.8.1/none/tests/ppc32/Makefile.am 2013-08-13 13:10:17.493219099 +0200 @@ -35,7 +35,10 @@ test_dfp2.stdout.exp_Without_dcffix \ test_dfp3.stderr.exp test_dfp3.stdout.exp test_dfp3.vgtest \ test_dfp4.stderr.exp test_dfp4.stdout.exp test_dfp4.vgtest \ - test_dfp5.stderr.exp test_dfp5.stdout.exp test_dfp5.vgtest + test_dfp5.stderr.exp test_dfp5.stdout.exp test_dfp5.vgtest \ + jm_vec_isa_2_07.stderr.exp jm_vec_isa_2_07.stdout.exp jm_vec_isa_2_07.vgtest \ + test_isa_2_07_part2.stderr.exp test_isa_2_07_part2.stdout.exp test_isa_2_07_part2.vgtest + check_PROGRAMS = \ allexec \ @@ -46,7 +49,9 @@ test_isa_2_06_part1 \ test_isa_2_06_part2 \ test_isa_2_06_part3 \ - test_dfp1 test_dfp2 test_dfp3 test_dfp4 test_dfp5 + test_dfp1 test_dfp2 test_dfp3 test_dfp4 test_dfp5 \ + test_isa_2_07_part1 \ + test_isa_2_07_part2 AM_CFLAGS += @FLAG_M32@ @@ -77,6 +82,14 @@ DFP_FLAG = endif +if HAS_ISA_2_07 +BUILD_FLAGS_ISA_2_07 = -mcpu=power8 +ISA_2_07_FLAG = -DHAS_ISA_2_07 +else +BUILD_FLAGS_ISA_2_07 = +ISA_2_07_FLAG = +endif + jm_insns_CFLAGS = $(AM_CFLAGS) -Winline -Wall -O -g -mregnames -maltivec \ @FLAG_M32@ $(ALTIVEC_FLAG) @@ -104,3 +117,9 @@ test_dfp5_CFLAGS = $(AM_CFLAGS) -Winline -Wall -O -lm -g -mregnames $(DFP_FLAG) \ @FLAG_M32@ $(BUILD_FLAGS_DFP) + +test_isa_2_07_part1_CFLAGS = $(AM_CFLAGS) -Winline -Wall -O -lm -g -mregnames $(ISA_2_07_FLAG) \ + @FLAG_M32@ $(BUILD_FLAGS_ISA_2_07) + +test_isa_2_07_part2_CFLAGS = $(AM_CFLAGS) -Winline -Wall -O -lm -g -mregnames $(ISA_2_07_FLAG) \ + @FLAG_M32@ $(BUILD_FLAGS_ISA_2_07) diff -ur valgrind-3.8.1.orig/none/tests/ppc32/Makefile.in valgrind-3.8.1/none/tests/ppc32/Makefile.in --- valgrind-3.8.1.orig/none/tests/ppc32/Makefile.in 2013-08-13 13:07:12.632886501 +0200 +++ valgrind-3.8.1/none/tests/ppc32/Makefile.in 2013-08-13 13:28:32.372024756 +0200 @@ -63,7 +63,8 @@ test_isa_2_06_part1$(EXEEXT) test_isa_2_06_part2$(EXEEXT) \ test_isa_2_06_part3$(EXEEXT) test_dfp1$(EXEEXT) \ test_dfp2$(EXEEXT) test_dfp3$(EXEEXT) test_dfp4$(EXEEXT) \ - test_dfp5$(EXEEXT) + test_dfp5$(EXEEXT) test_isa_2_07_part1$(EXEEXT) \ + test_isa_2_07_part2$(EXEEXT) subdir = none/tests/ppc32 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/configure.in @@ -164,6 +165,18 @@ test_isa_2_06_part3_LDADD = $(LDADD) test_isa_2_06_part3_LINK = $(CCLD) $(test_isa_2_06_part3_CFLAGS) \ $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ +test_isa_2_07_part1_SOURCES = test_isa_2_07_part1.c +test_isa_2_07_part1_OBJECTS = \ + test_isa_2_07_part1-test_isa_2_07_part1.$(OBJEXT) +test_isa_2_07_part1_LDADD = $(LDADD) +test_isa_2_07_part1_LINK = $(CCLD) $(test_isa_2_07_part1_CFLAGS) \ + $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ +test_isa_2_07_part2_SOURCES = test_isa_2_07_part2.c +test_isa_2_07_part2_OBJECTS = \ + test_isa_2_07_part2-test_isa_2_07_part2.$(OBJEXT) +test_isa_2_07_part2_LDADD = $(LDADD) +test_isa_2_07_part2_LINK = $(CCLD) $(test_isa_2_07_part2_CFLAGS) \ + $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ tw_SOURCES = tw.c tw_OBJECTS = tw.$(OBJEXT) tw_LDADD = $(LDADD) @@ -187,13 +200,15 @@ power6_bcmp.c round.c testVMX.c test_dfp1.c test_dfp2.c \ test_dfp3.c test_dfp4.c test_dfp5.c test_fx.c test_gx.c \ test_isa_2_06_part1.c test_isa_2_06_part2.c \ - test_isa_2_06_part3.c tw.c twi.c xlc_dbl_u32.c + test_isa_2_06_part3.c test_isa_2_07_part1.c \ + test_isa_2_07_part2.c tw.c twi.c xlc_dbl_u32.c DIST_SOURCES = allexec.c bug129390-ppc32.c bug139050-ppc32.c \ jm-insns.c ldstrev.c lsw.c mcrfs.c mftocrf.c power5+_round.c \ power6_bcmp.c round.c testVMX.c test_dfp1.c test_dfp2.c \ test_dfp3.c test_dfp4.c test_dfp5.c test_fx.c test_gx.c \ test_isa_2_06_part1.c test_isa_2_06_part2.c \ - test_isa_2_06_part3.c tw.c twi.c xlc_dbl_u32.c + test_isa_2_06_part3.c test_isa_2_07_part1.c \ + test_isa_2_07_part2.c tw.c twi.c xlc_dbl_u32.c ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) @@ -507,7 +522,9 @@ test_dfp2.stdout.exp_Without_dcffix \ test_dfp3.stderr.exp test_dfp3.stdout.exp test_dfp3.vgtest \ test_dfp4.stderr.exp test_dfp4.stdout.exp test_dfp4.vgtest \ - test_dfp5.stderr.exp test_dfp5.stdout.exp test_dfp5.vgtest + test_dfp5.stderr.exp test_dfp5.stdout.exp test_dfp5.vgtest \ + jm_vec_isa_2_07.stderr.exp jm_vec_isa_2_07.stdout.exp jm_vec_isa_2_07.vgtest \ + test_isa_2_07_part2.stderr.exp test_isa_2_07_part2.stdout.exp test_isa_2_07_part2.vgtest allexec_CFLAGS = $(AM_CFLAGS) @FLAG_W_NO_NONNULL@ @HAS_ALTIVEC_FALSE@ALTIVEC_FLAG = @@ -520,6 +537,10 @@ @HAS_DFP_TRUE@BUILD_FLAGS_DFP = -mhard-dfp -mcpu=power6 @HAS_DFP_FALSE@DFP_FLAG = @HAS_DFP_TRUE@DFP_FLAG = -DHAS_DFP +@HAS_ISA_2_07_FALSE@BUILD_FLAGS_ISA_2_07 = +@HAS_ISA_2_07_TRUE@BUILD_FLAGS_ISA_2_07 = -mcpu=power8 +@HAS_ISA_2_07_FALSE@ISA_2_07_FLAG = +@HAS_ISA_2_07_TRUE@ISA_2_07_FLAG = -DHAS_ISA_2_07 jm_insns_CFLAGS = $(AM_CFLAGS) -Winline -Wall -O -g -mregnames -maltivec \ @FLAG_M32@ $(ALTIVEC_FLAG) @@ -550,6 +571,12 @@ test_dfp5_CFLAGS = $(AM_CFLAGS) -Winline -Wall -O -lm -g -mregnames $(DFP_FLAG) \ @FLAG_M32@ $(BUILD_FLAGS_DFP) +test_isa_2_07_part1_CFLAGS = $(AM_CFLAGS) -Winline -Wall -O -lm -g -mregnames $(ISA_2_07_FLAG) \ + @FLAG_M32@ $(BUILD_FLAGS_ISA_2_07) + +test_isa_2_07_part2_CFLAGS = $(AM_CFLAGS) -Winline -Wall -O -lm -g -mregnames $(ISA_2_07_FLAG) \ + @FLAG_M32@ $(BUILD_FLAGS_ISA_2_07) + all: all-am .SUFFIXES: @@ -653,6 +680,12 @@ test_isa_2_06_part3$(EXEEXT): $(test_isa_2_06_part3_OBJECTS) $(test_isa_2_06_part3_DEPENDENCIES) @rm -f test_isa_2_06_part3$(EXEEXT) $(test_isa_2_06_part3_LINK) $(test_isa_2_06_part3_OBJECTS) $(test_isa_2_06_part3_LDADD) $(LIBS) +test_isa_2_07_part1$(EXEEXT): $(test_isa_2_07_part1_OBJECTS) $(test_isa_2_07_part1_DEPENDENCIES) + @rm -f test_isa_2_07_part1$(EXEEXT) + $(test_isa_2_07_part1_LINK) $(test_isa_2_07_part1_OBJECTS) $(test_isa_2_07_part1_LDADD) $(LIBS) +test_isa_2_07_part2$(EXEEXT): $(test_isa_2_07_part2_OBJECTS) $(test_isa_2_07_part2_DEPENDENCIES) + @rm -f test_isa_2_07_part2$(EXEEXT) + $(test_isa_2_07_part2_LINK) $(test_isa_2_07_part2_OBJECTS) $(test_isa_2_07_part2_LDADD) $(LIBS) tw$(EXEEXT): $(tw_OBJECTS) $(tw_DEPENDENCIES) @rm -f tw$(EXEEXT) $(LINK) $(tw_OBJECTS) $(tw_LDADD) $(LIBS) @@ -691,6 +724,8 @@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_isa_2_06_part1-test_isa_2_06_part1.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_isa_2_06_part2-test_isa_2_06_part2.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_isa_2_06_part3-test_isa_2_06_part3.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_isa_2_07_part1-test_isa_2_07_part1.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_isa_2_07_part2-test_isa_2_07_part2.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tw.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/twi.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xlc_dbl_u32.Po@am__quote@ @@ -863,6 +898,34 @@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_isa_2_06_part3_CFLAGS) $(CFLAGS) -c -o test_isa_2_06_part3-test_isa_2_06_part3.obj `if test -f 'test_isa_2_06_part3.c'; then $(CYGPATH_W) 'test_isa_2_06_part3.c'; else $(CYGPATH_W) '$(srcdir)/test_isa_2_06_part3.c'; fi` +test_isa_2_07_part1-test_isa_2_07_part1.o: test_isa_2_07_part1.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_isa_2_07_part1_CFLAGS) $(CFLAGS) -MT test_isa_2_07_part1-test_isa_2_07_part1.o -MD -MP -MF $(DEPDIR)/test_isa_2_07_part1-test_isa_2_07_part1.Tpo -c -o test_isa_2_07_part1-test_isa_2_07_part1.o `test -f 'test_isa_2_07_part1.c' || echo '$(srcdir)/'`test_isa_2_07_part1.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/test_isa_2_07_part1-test_isa_2_07_part1.Tpo $(DEPDIR)/test_isa_2_07_part1-test_isa_2_07_part1.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='test_isa_2_07_part1.c' object='test_isa_2_07_part1-test_isa_2_07_part1.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_isa_2_07_part1_CFLAGS) $(CFLAGS) -c -o test_isa_2_07_part1-test_isa_2_07_part1.o `test -f 'test_isa_2_07_part1.c' || echo '$(srcdir)/'`test_isa_2_07_part1.c + +test_isa_2_07_part1-test_isa_2_07_part1.obj: test_isa_2_07_part1.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_isa_2_07_part1_CFLAGS) $(CFLAGS) -MT test_isa_2_07_part1-test_isa_2_07_part1.obj -MD -MP -MF $(DEPDIR)/test_isa_2_07_part1-test_isa_2_07_part1.Tpo -c -o test_isa_2_07_part1-test_isa_2_07_part1.obj `if test -f 'test_isa_2_07_part1.c'; then $(CYGPATH_W) 'test_isa_2_07_part1.c'; else $(CYGPATH_W) '$(srcdir)/test_isa_2_07_part1.c'; fi` +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/test_isa_2_07_part1-test_isa_2_07_part1.Tpo $(DEPDIR)/test_isa_2_07_part1-test_isa_2_07_part1.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='test_isa_2_07_part1.c' object='test_isa_2_07_part1-test_isa_2_07_part1.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_isa_2_07_part1_CFLAGS) $(CFLAGS) -c -o test_isa_2_07_part1-test_isa_2_07_part1.obj `if test -f 'test_isa_2_07_part1.c'; then $(CYGPATH_W) 'test_isa_2_07_part1.c'; else $(CYGPATH_W) '$(srcdir)/test_isa_2_07_part1.c'; fi` + +test_isa_2_07_part2-test_isa_2_07_part2.o: test_isa_2_07_part2.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_isa_2_07_part2_CFLAGS) $(CFLAGS) -MT test_isa_2_07_part2-test_isa_2_07_part2.o -MD -MP -MF $(DEPDIR)/test_isa_2_07_part2-test_isa_2_07_part2.Tpo -c -o test_isa_2_07_part2-test_isa_2_07_part2.o `test -f 'test_isa_2_07_part2.c' || echo '$(srcdir)/'`test_isa_2_07_part2.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/test_isa_2_07_part2-test_isa_2_07_part2.Tpo $(DEPDIR)/test_isa_2_07_part2-test_isa_2_07_part2.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='test_isa_2_07_part2.c' object='test_isa_2_07_part2-test_isa_2_07_part2.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_isa_2_07_part2_CFLAGS) $(CFLAGS) -c -o test_isa_2_07_part2-test_isa_2_07_part2.o `test -f 'test_isa_2_07_part2.c' || echo '$(srcdir)/'`test_isa_2_07_part2.c + +test_isa_2_07_part2-test_isa_2_07_part2.obj: test_isa_2_07_part2.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_isa_2_07_part2_CFLAGS) $(CFLAGS) -MT test_isa_2_07_part2-test_isa_2_07_part2.obj -MD -MP -MF $(DEPDIR)/test_isa_2_07_part2-test_isa_2_07_part2.Tpo -c -o test_isa_2_07_part2-test_isa_2_07_part2.obj `if test -f 'test_isa_2_07_part2.c'; then $(CYGPATH_W) 'test_isa_2_07_part2.c'; else $(CYGPATH_W) '$(srcdir)/test_isa_2_07_part2.c'; fi` +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/test_isa_2_07_part2-test_isa_2_07_part2.Tpo $(DEPDIR)/test_isa_2_07_part2-test_isa_2_07_part2.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='test_isa_2_07_part2.c' object='test_isa_2_07_part2-test_isa_2_07_part2.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_isa_2_07_part2_CFLAGS) $(CFLAGS) -c -o test_isa_2_07_part2-test_isa_2_07_part2.obj `if test -f 'test_isa_2_07_part2.c'; then $(CYGPATH_W) 'test_isa_2_07_part2.c'; else $(CYGPATH_W) '$(srcdir)/test_isa_2_07_part2.c'; fi` + ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ diff -ur valgrind-3.8.1.orig/none/tests/ppc64/Makefile.am valgrind-3.8.1/none/tests/ppc64/Makefile.am --- valgrind-3.8.1.orig/none/tests/ppc64/Makefile.am 2013-08-13 13:07:12.675886811 +0200 +++ valgrind-3.8.1/none/tests/ppc64/Makefile.am 2013-08-13 13:10:17.496219122 +0200 @@ -23,12 +23,16 @@ test_dfp2.stdout.exp_Without_dcffix \ test_dfp3.stderr.exp test_dfp3.stdout.exp test_dfp3.vgtest \ test_dfp4.stderr.exp test_dfp4.stdout.exp test_dfp4.vgtest \ - test_dfp5.stderr.exp test_dfp5.stdout.exp test_dfp5.vgtest + test_dfp5.stderr.exp test_dfp5.stdout.exp test_dfp5.vgtest \ + jm_vec_isa_2_07.stderr.exp jm_vec_isa_2_07.stdout.exp jm_vec_isa_2_07.vgtest \ + test_isa_2_07_part2.stderr.exp test_isa_2_07_part2.stdout.exp test_isa_2_07_part2.vgtest check_PROGRAMS = \ allexec \ - jm-insns lsw round std_reg_imm twi_tdi tw_td power6_bcmp power6_mf_gpr test_isa_2_06_part1 \ - test_isa_2_06_part2 test_isa_2_06_part3 test_dfp1 test_dfp2 test_dfp3 test_dfp4 test_dfp5 + jm-insns lsw round std_reg_imm twi_tdi tw_td power6_bcmp \ + power6_mf_gpr test_isa_2_06_part1 test_isa_2_06_part2 \ + test_isa_2_06_part3 test_dfp1 test_dfp2 test_dfp3 test_dfp4 \ + test_dfp5 test_isa_2_07_part1 test_isa_2_07_part2 AM_CFLAGS += @FLAG_M64@ AM_CXXFLAGS += @FLAG_M64@ @@ -58,6 +62,14 @@ DFP_FLAG = endif +if HAS_ISA_2_07 +BUILD_FLAGS_ISA_2_07 = -mcpu=power8 +ISA_2_07_FLAG = -DHAS_ISA_2_07 +else +BUILD_FLAGS_ISA_2_07 = +ISA_2_07_FLAG = +endif + test_isa_2_06_part1_CFLAGS = $(AM_CFLAGS) -Winline -Wall -O -g -mregnames $(VSX_FLAG) \ @FLAG_M64@ $(ALTIVEC_FLAG) $(BUILD_FLAG_VSX) @@ -84,3 +96,8 @@ test_dfp5_CFLAGS = $(AM_CFLAGS) -Winline -Wall -O -lm -g -mregnames $(DFP_FLAG) \ @FLAG_M64@ $(BUILD_FLAGS_DFP) +test_isa_2_07_part1_CFLAGS = $(AM_CFLAGS) -Winline -Wall -O -lm -g -mregnames $(ISA_2_07_FLAG) \ + @FLAG_M64@ $(BUILD_FLAGS_ISA_2_07) + +test_isa_2_07_part2_CFLAGS = $(AM_CFLAGS) -Winline -Wall -O -lm -g -mregnames $(ISA_2_07_FLAG) \ + @FLAG_M64@ $(BUILD_FLAGS_ISA_2_07) diff -ur valgrind-3.8.1.orig/none/tests/ppc64/Makefile.in valgrind-3.8.1/none/tests/ppc64/Makefile.in --- valgrind-3.8.1.orig/none/tests/ppc64/Makefile.in 2013-08-13 13:07:12.674886804 +0200 +++ valgrind-3.8.1/none/tests/ppc64/Makefile.in 2013-08-13 13:28:32.460025381 +0200 @@ -60,7 +60,8 @@ test_isa_2_06_part1$(EXEEXT) test_isa_2_06_part2$(EXEEXT) \ test_isa_2_06_part3$(EXEEXT) test_dfp1$(EXEEXT) \ test_dfp2$(EXEEXT) test_dfp3$(EXEEXT) test_dfp4$(EXEEXT) \ - test_dfp5$(EXEEXT) + test_dfp5$(EXEEXT) test_isa_2_07_part1$(EXEEXT) \ + test_isa_2_07_part2$(EXEEXT) subdir = none/tests/ppc64 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/configure.in @@ -138,6 +139,18 @@ test_isa_2_06_part3_LDADD = $(LDADD) test_isa_2_06_part3_LINK = $(CCLD) $(test_isa_2_06_part3_CFLAGS) \ $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ +test_isa_2_07_part1_SOURCES = test_isa_2_07_part1.c +test_isa_2_07_part1_OBJECTS = \ + test_isa_2_07_part1-test_isa_2_07_part1.$(OBJEXT) +test_isa_2_07_part1_LDADD = $(LDADD) +test_isa_2_07_part1_LINK = $(CCLD) $(test_isa_2_07_part1_CFLAGS) \ + $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ +test_isa_2_07_part2_SOURCES = test_isa_2_07_part2.c +test_isa_2_07_part2_OBJECTS = \ + test_isa_2_07_part2-test_isa_2_07_part2.$(OBJEXT) +test_isa_2_07_part2_LDADD = $(LDADD) +test_isa_2_07_part2_LINK = $(CCLD) $(test_isa_2_07_part2_CFLAGS) \ + $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ tw_td_SOURCES = tw_td.c tw_td_OBJECTS = tw_td.$(OBJEXT) tw_td_LDADD = $(LDADD) @@ -156,11 +169,13 @@ SOURCES = allexec.c jm-insns.c lsw.c power6_bcmp.c power6_mf_gpr.c \ round.c std_reg_imm.c test_dfp1.c test_dfp2.c test_dfp3.c \ test_dfp4.c test_dfp5.c test_isa_2_06_part1.c \ - test_isa_2_06_part2.c test_isa_2_06_part3.c tw_td.c twi_tdi.c + test_isa_2_06_part2.c test_isa_2_06_part3.c \ + test_isa_2_07_part1.c test_isa_2_07_part2.c tw_td.c twi_tdi.c DIST_SOURCES = allexec.c jm-insns.c lsw.c power6_bcmp.c \ power6_mf_gpr.c round.c std_reg_imm.c test_dfp1.c test_dfp2.c \ test_dfp3.c test_dfp4.c test_dfp5.c test_isa_2_06_part1.c \ - test_isa_2_06_part2.c test_isa_2_06_part3.c tw_td.c twi_tdi.c + test_isa_2_06_part2.c test_isa_2_06_part3.c \ + test_isa_2_07_part1.c test_isa_2_07_part2.c tw_td.c twi_tdi.c ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) @@ -462,7 +477,9 @@ test_dfp2.stdout.exp_Without_dcffix \ test_dfp3.stderr.exp test_dfp3.stdout.exp test_dfp3.vgtest \ test_dfp4.stderr.exp test_dfp4.stdout.exp test_dfp4.vgtest \ - test_dfp5.stderr.exp test_dfp5.stdout.exp test_dfp5.vgtest + test_dfp5.stderr.exp test_dfp5.stdout.exp test_dfp5.vgtest \ + jm_vec_isa_2_07.stderr.exp jm_vec_isa_2_07.stdout.exp jm_vec_isa_2_07.vgtest \ + test_isa_2_07_part2.stderr.exp test_isa_2_07_part2.stdout.exp test_isa_2_07_part2.vgtest allexec_CFLAGS = $(AM_CFLAGS) @FLAG_W_NO_NONNULL@ @HAS_ALTIVEC_FALSE@ALTIVEC_FLAG = @@ -475,6 +492,10 @@ @HAS_DFP_TRUE@BUILD_FLAGS_DFP = -mhard-dfp -mcpu=power6 @HAS_DFP_FALSE@DFP_FLAG = @HAS_DFP_TRUE@DFP_FLAG = -DHAS_DFP +@HAS_ISA_2_07_FALSE@BUILD_FLAGS_ISA_2_07 = +@HAS_ISA_2_07_TRUE@BUILD_FLAGS_ISA_2_07 = -mcpu=power8 +@HAS_ISA_2_07_FALSE@ISA_2_07_FLAG = +@HAS_ISA_2_07_TRUE@ISA_2_07_FLAG = -DHAS_ISA_2_07 test_isa_2_06_part1_CFLAGS = $(AM_CFLAGS) -Winline -Wall -O -g -mregnames $(VSX_FLAG) \ @FLAG_M64@ $(ALTIVEC_FLAG) $(BUILD_FLAG_VSX) @@ -502,6 +523,12 @@ test_dfp5_CFLAGS = $(AM_CFLAGS) -Winline -Wall -O -lm -g -mregnames $(DFP_FLAG) \ @FLAG_M64@ $(BUILD_FLAGS_DFP) +test_isa_2_07_part1_CFLAGS = $(AM_CFLAGS) -Winline -Wall -O -lm -g -mregnames $(ISA_2_07_FLAG) \ + @FLAG_M64@ $(BUILD_FLAGS_ISA_2_07) + +test_isa_2_07_part2_CFLAGS = $(AM_CFLAGS) -Winline -Wall -O -lm -g -mregnames $(ISA_2_07_FLAG) \ + @FLAG_M64@ $(BUILD_FLAGS_ISA_2_07) + all: all-am .SUFFIXES: @@ -584,6 +611,12 @@ test_isa_2_06_part3$(EXEEXT): $(test_isa_2_06_part3_OBJECTS) $(test_isa_2_06_part3_DEPENDENCIES) @rm -f test_isa_2_06_part3$(EXEEXT) $(test_isa_2_06_part3_LINK) $(test_isa_2_06_part3_OBJECTS) $(test_isa_2_06_part3_LDADD) $(LIBS) +test_isa_2_07_part1$(EXEEXT): $(test_isa_2_07_part1_OBJECTS) $(test_isa_2_07_part1_DEPENDENCIES) + @rm -f test_isa_2_07_part1$(EXEEXT) + $(test_isa_2_07_part1_LINK) $(test_isa_2_07_part1_OBJECTS) $(test_isa_2_07_part1_LDADD) $(LIBS) +test_isa_2_07_part2$(EXEEXT): $(test_isa_2_07_part2_OBJECTS) $(test_isa_2_07_part2_DEPENDENCIES) + @rm -f test_isa_2_07_part2$(EXEEXT) + $(test_isa_2_07_part2_LINK) $(test_isa_2_07_part2_OBJECTS) $(test_isa_2_07_part2_LDADD) $(LIBS) tw_td$(EXEEXT): $(tw_td_OBJECTS) $(tw_td_DEPENDENCIES) @rm -f tw_td$(EXEEXT) $(LINK) $(tw_td_OBJECTS) $(tw_td_LDADD) $(LIBS) @@ -612,6 +645,8 @@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_isa_2_06_part1-test_isa_2_06_part1.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_isa_2_06_part2-test_isa_2_06_part2.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_isa_2_06_part3-test_isa_2_06_part3.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_isa_2_07_part1-test_isa_2_07_part1.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_isa_2_07_part2-test_isa_2_07_part2.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tw_td.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/twi_tdi.Po@am__quote@ @@ -769,6 +804,34 @@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_isa_2_06_part3_CFLAGS) $(CFLAGS) -c -o test_isa_2_06_part3-test_isa_2_06_part3.obj `if test -f 'test_isa_2_06_part3.c'; then $(CYGPATH_W) 'test_isa_2_06_part3.c'; else $(CYGPATH_W) '$(srcdir)/test_isa_2_06_part3.c'; fi` +test_isa_2_07_part1-test_isa_2_07_part1.o: test_isa_2_07_part1.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_isa_2_07_part1_CFLAGS) $(CFLAGS) -MT test_isa_2_07_part1-test_isa_2_07_part1.o -MD -MP -MF $(DEPDIR)/test_isa_2_07_part1-test_isa_2_07_part1.Tpo -c -o test_isa_2_07_part1-test_isa_2_07_part1.o `test -f 'test_isa_2_07_part1.c' || echo '$(srcdir)/'`test_isa_2_07_part1.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/test_isa_2_07_part1-test_isa_2_07_part1.Tpo $(DEPDIR)/test_isa_2_07_part1-test_isa_2_07_part1.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='test_isa_2_07_part1.c' object='test_isa_2_07_part1-test_isa_2_07_part1.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_isa_2_07_part1_CFLAGS) $(CFLAGS) -c -o test_isa_2_07_part1-test_isa_2_07_part1.o `test -f 'test_isa_2_07_part1.c' || echo '$(srcdir)/'`test_isa_2_07_part1.c + +test_isa_2_07_part1-test_isa_2_07_part1.obj: test_isa_2_07_part1.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_isa_2_07_part1_CFLAGS) $(CFLAGS) -MT test_isa_2_07_part1-test_isa_2_07_part1.obj -MD -MP -MF $(DEPDIR)/test_isa_2_07_part1-test_isa_2_07_part1.Tpo -c -o test_isa_2_07_part1-test_isa_2_07_part1.obj `if test -f 'test_isa_2_07_part1.c'; then $(CYGPATH_W) 'test_isa_2_07_part1.c'; else $(CYGPATH_W) '$(srcdir)/test_isa_2_07_part1.c'; fi` +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/test_isa_2_07_part1-test_isa_2_07_part1.Tpo $(DEPDIR)/test_isa_2_07_part1-test_isa_2_07_part1.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='test_isa_2_07_part1.c' object='test_isa_2_07_part1-test_isa_2_07_part1.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_isa_2_07_part1_CFLAGS) $(CFLAGS) -c -o test_isa_2_07_part1-test_isa_2_07_part1.obj `if test -f 'test_isa_2_07_part1.c'; then $(CYGPATH_W) 'test_isa_2_07_part1.c'; else $(CYGPATH_W) '$(srcdir)/test_isa_2_07_part1.c'; fi` + +test_isa_2_07_part2-test_isa_2_07_part2.o: test_isa_2_07_part2.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_isa_2_07_part2_CFLAGS) $(CFLAGS) -MT test_isa_2_07_part2-test_isa_2_07_part2.o -MD -MP -MF $(DEPDIR)/test_isa_2_07_part2-test_isa_2_07_part2.Tpo -c -o test_isa_2_07_part2-test_isa_2_07_part2.o `test -f 'test_isa_2_07_part2.c' || echo '$(srcdir)/'`test_isa_2_07_part2.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/test_isa_2_07_part2-test_isa_2_07_part2.Tpo $(DEPDIR)/test_isa_2_07_part2-test_isa_2_07_part2.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='test_isa_2_07_part2.c' object='test_isa_2_07_part2-test_isa_2_07_part2.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_isa_2_07_part2_CFLAGS) $(CFLAGS) -c -o test_isa_2_07_part2-test_isa_2_07_part2.o `test -f 'test_isa_2_07_part2.c' || echo '$(srcdir)/'`test_isa_2_07_part2.c + +test_isa_2_07_part2-test_isa_2_07_part2.obj: test_isa_2_07_part2.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_isa_2_07_part2_CFLAGS) $(CFLAGS) -MT test_isa_2_07_part2-test_isa_2_07_part2.obj -MD -MP -MF $(DEPDIR)/test_isa_2_07_part2-test_isa_2_07_part2.Tpo -c -o test_isa_2_07_part2-test_isa_2_07_part2.obj `if test -f 'test_isa_2_07_part2.c'; then $(CYGPATH_W) 'test_isa_2_07_part2.c'; else $(CYGPATH_W) '$(srcdir)/test_isa_2_07_part2.c'; fi` +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/test_isa_2_07_part2-test_isa_2_07_part2.Tpo $(DEPDIR)/test_isa_2_07_part2-test_isa_2_07_part2.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='test_isa_2_07_part2.c' object='test_isa_2_07_part2-test_isa_2_07_part2.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_isa_2_07_part2_CFLAGS) $(CFLAGS) -c -o test_isa_2_07_part2-test_isa_2_07_part2.obj `if test -f 'test_isa_2_07_part2.c'; then $(CYGPATH_W) 'test_isa_2_07_part2.c'; else $(CYGPATH_W) '$(srcdir)/test_isa_2_07_part2.c'; fi` + ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ diff -ur valgrind-3.8.1.orig/tests/check_isa-2_06_cap valgrind-3.8.1/tests/check_isa-2_06_cap --- valgrind-3.8.1.orig/tests/check_isa-2_06_cap 2013-08-13 13:07:12.820887858 +0200 +++ valgrind-3.8.1/tests/check_isa-2_06_cap 2013-08-13 13:10:17.500219150 +0200 @@ -1,8 +1,9 @@ #!/bin/sh -# We use this script to check whether or not the processor supports Power ISA 2.06. +# We use this script to check whether or not the processor supports Power ISA 2.06 or later. +DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" +LD_SHOW_AUXV=1 $DIR/true | grep arch_2_06 > /dev/null 2>&1 -LD_SHOW_AUXV=1 /bin/true | grep arch_2_06 > /dev/null 2>&1 if [ "$?" -ne "0" ]; then exit 1 else diff -ur valgrind-3.8.1.orig/VEX/priv/guest_ppc_toIR.c valgrind-3.8.1/VEX/priv/guest_ppc_toIR.c --- valgrind-3.8.1.orig/VEX/priv/guest_ppc_toIR.c 2013-08-13 13:07:12.730887208 +0200 +++ valgrind-3.8.1/VEX/priv/guest_ppc_toIR.c 2013-08-13 13:10:17.465218898 +0200 @@ -4918,11 +4918,17 @@ case 0x3E: switch ((b1<<1) | b0) { case 0x0: // std (Store DWord, PPC64 p580) + if (!mode64) + return False; + DIP("std r%u,%d(r%u)\n", rS_addr, simm16, rA_addr); storeBE( mkexpr(EA), mkexpr(rS) ); break; case 0x1: // stdu (Store DWord, Update, PPC64 p583) + if (!mode64) + return False; + DIP("stdu r%u,%d(r%u)\n", rS_addr, simm16, rA_addr); putIReg( rA_addr, mkexpr(EA) ); storeBE( mkexpr(EA), mkexpr(rS) ); @@ -6452,7 +6458,7 @@ } /* not decodable */ return False; - + /* XFX-Form */ case 0x153: // mfspr (Move from Special-Purpose Register, PPC32 p470) @@ -6620,7 +6626,79 @@ return False; } break; - + + case 0x33: // mfvsrd + { + UChar XS = ifieldRegXS( theInstr ); + UChar rA_addr = ifieldRegA(theInstr); + IRExpr * high64; + IRTemp vS = newTemp( Ity_V128 ); + DIP("mfvsrd r%u,vsr%d\n", rA_addr, (UInt)XS); + + /* XS = SX || S + * For SX=0, mfvsrd is treated as a Floating-Point + * instruction in terms of resource availability. + * For SX=1, mfvsrd is treated as a Vector instruction in + * terms of resource availability. + *NEED TO FIGURE OUT HOW TO IMPLEMENT THE RESOURCE AVAILABILITY PART + */ + assign( vS, getVSReg( XS ) ); + high64 = unop( Iop_V128HIto64, mkexpr( vS ) ); + putIReg( rA_addr, (mode64) ? high64 : + unop( Iop_64to32, high64 ) ); + break; + } + + case 0xB3: // mtvsrd + { + UChar XT = ifieldRegXT( theInstr ); + UChar rA_addr = ifieldRegA(theInstr); + IRTemp rA = newTemp(ty); + DIP("mtvsrd vsr%d,r%u\n", (UInt)XT, rA_addr); + /* XS = SX || S + * For SX=0, mfvsrd is treated as a Floating-Point + * instruction in terms of resource availability. + * For SX=1, mfvsrd is treated as a Vector instruction in + * terms of resource availability. + *NEED TO FIGURE OUT HOW TO IMPLEMENT THE RESOURCE AVAILABILITY PART + */ + assign( rA, getIReg(rA_addr) ); + + if (mode64) + putVSReg( XT, binop( Iop_64HLtoV128, mkexpr( rA ), mkU64( 0 ) ) ); + else + putVSReg( XT, binop( Iop_64HLtoV128, + binop( Iop_32HLto64, + mkU32( 0 ), + mkexpr( rA ) ), + mkU64( 0 ) ) ); + break; + } + + case 0xD3: // mtvsrwa + { + UChar XT = ifieldRegXT( theInstr ); + UChar rA_addr = ifieldRegA(theInstr); + IRTemp rA = newTemp( Ity_I32 ); + DIP("mtvsrwa vsr%d,r%u\n", (UInt)XT, rA_addr); + /* XS = SX || S + * For SX=0, mtvsrwa is treated as a Floating-Point + * instruction in terms of resource availability. + * For SX=1, mtvsrwa is treated as a Vector instruction in + * terms of resource availability. + *NEED TO FIGURE OUT HOW TO IMPLEMENT THE RESOURCE AVAILABILITY PART + */ + if (mode64) + assign( rA, unop( Iop_64to32, getIReg( rA_addr ) ) ); + else + assign( rA, getIReg(rA_addr) ); + + putVSReg( XT, binop( Iop_64HLtoV128, + unop( Iop_32Sto64, mkexpr( rA ) ), + mkU64( 0 ) ) ); + break; + } + default: vex_printf("dis_proc_ctl(ppc)(opc2)\n"); return False; @@ -11635,7 +11713,7 @@ /* Create and assign temps only as needed for the given instruction. */ switch (opc2) { // scalar double-precision floating point argument - case 0x2B0: case 0x0b0: case 0x290: case 0x212: case 0x090: + case 0x2B0: case 0x0b0: case 0x290: case 0x212: case 0x216: case 0x090: xB = newTemp(Ity_F64); assign( xB, unop( Iop_ReinterpI64asF64, @@ -11677,6 +11755,11 @@ assign( xB, unop( Iop_64HIto32, unop( Iop_V128HIto64, getVSReg( XB ) ) ) ); break; + case 0x296: // xscvspdpn (non signaling version of xscvpdp) + xB = newTemp(Ity_I32); + assign( xB, + unop( Iop_64HIto32, unop( Iop_V128HIto64, getVSReg( XB ) ) ) ); + break; /* Certain instructions have their complete implementation in the main switch statement * that follows this one; thus we have a "do nothing" case for those instructions here. @@ -11824,6 +11907,18 @@ mkU32( 0 ) ), mkU64( 0ULL ) ) ); break; + case 0x216: /* xscvdpspn (VSX Scalar convert scalar Single-Precision to + vector single Convert to Single-Precision non-signalling */ + DIP("xscvdpspn v%u,v%u\n", (UInt)XT, (UInt)XB); + putVSReg( XT, + binop( Iop_64HLtoV128, + binop( Iop_32HLto64, + unop( Iop_ReinterpF32asI32, + unop( Iop_TruncF64asF32, + mkexpr( xB ) ) ), + mkU32( 0 ) ), + mkU64( 0ULL ) ) ); + break; case 0x090: // xscvdpuxws (VSX Scalar truncate Double-Precision to integer // and Convert to Unsigned Integer Word format with Saturate) DIP("xscvdpuxws v%u,v%u\n", (UInt)XT, (UInt)XB); @@ -11845,6 +11940,15 @@ unop( Iop_ReinterpI32asF32, mkexpr( xB ) ) ) ), mkU64( 0ULL ) ) ); break; + case 0x296: // xscvspdpn (VSX Scalar Convert Single-Precision to Double-Precision format Non signaling) + DIP("xscvspdpn v%u,v%u\n", (UInt)XT, (UInt)XB); + putVSReg( XT, + binop( Iop_64HLtoV128, + unop( Iop_ReinterpF64asI64, + unop( Iop_F32toF64, + unop( Iop_ReinterpI32asF32, mkexpr( xB ) ) ) ), + mkU64( 0ULL ) ) ); + break; case 0x312: // xvcvdpsp (VSX Vector round Double-Precision to single-precision // and Convert to Single-Precision format) DIP("xvcvdpsp v%u,v%u\n", (UInt)XT, (UInt)XB); @@ -14552,6 +14656,11 @@ putVReg( vD_addr, binop(Iop_Add32x4, mkexpr(vA), mkexpr(vB)) ); break; + case 0x0C0: // vaddudm (Add Unsigned Double Word Modulo) + DIP("vaddudm v%d,v%d,v%d\n", vD_addr, vA_addr, vB_addr); + putVReg( vD_addr, binop(Iop_Add64x2, mkexpr(vA), mkexpr(vB)) ); + break; + case 0x200: // vaddubs (Add Unsigned Byte Saturate, AV p142) DIP("vaddubs v%d,v%d,v%d\n", vD_addr, vA_addr, vB_addr); putVReg( vD_addr, binop(Iop_QAdd8Ux16, mkexpr(vA), mkexpr(vB)) ); @@ -15824,6 +15933,12 @@ return True; } + case 0x44E: // vpkudum (Pack Unsigned Double Word Unsigned Modulo) + DIP("vpkudum v%d,v%d,v%d\n", vD_addr, vA_addr, vB_addr); + putVReg( vD_addr, + binop(Iop_NarrowBin64to32x4, mkexpr(vA), mkexpr(vB)) ); + return True; + default: break; // Fall through... } @@ -16356,6 +16471,7 @@ { 0x1f4, "xvtdivdp" }, { 0x208, "xxland" }, { 0x212, "xscvdpsp" }, + { 0x216, "xscvdpspn" }, { 0x228, "xxlandc" }, { 0x248 , "xxlor" }, { 0x268, "xxlxor" }, @@ -16364,6 +16480,7 @@ { 0x288, "xxlnor" }, { 0x290, "xscvdpuxds" }, { 0x292, "xscvspdp" }, + { 0x296, "xscvspdpn" }, { 0x2a0, "xsmindp" }, { 0x2a4, "xsnmaddmdp" }, { 0x2b0, "xscvdpsxds" }, @@ -16412,7 +16529,8 @@ { 0x3f0, "xvcvsxddp" }, { 0x3f2, "xvnegdp" } }; -#define VSX_ALL_LEN 135 +#define VSX_ALL_LEN (sizeof vsx_all / sizeof *vsx_all) + // ATTENTION: This search function assumes vsx_all array is sorted. static Int findVSXextOpCode(UInt opcode) @@ -16490,6 +16608,7 @@ Bool allow_GX = False; Bool allow_VX = False; // Equates to "supports Power ISA 2.06 Bool allow_DFP = False; + Bool allow_isa_2_07 = False; UInt hwcaps = archinfo->hwcaps; Long delta; @@ -16501,6 +16620,7 @@ allow_GX = (0 != (hwcaps & VEX_HWCAPS_PPC64_GX)); allow_VX = (0 != (hwcaps & VEX_HWCAPS_PPC64_VX)); allow_DFP = (0 != (hwcaps & VEX_HWCAPS_PPC64_DFP)); + allow_isa_2_07 = (0 != (hwcaps & VEX_HWCAPS_PPC64_ISA2_07)); } else { allow_F = (0 != (hwcaps & VEX_HWCAPS_PPC32_F)); allow_V = (0 != (hwcaps & VEX_HWCAPS_PPC32_V)); @@ -16508,6 +16628,7 @@ allow_GX = (0 != (hwcaps & VEX_HWCAPS_PPC32_GX)); allow_VX = (0 != (hwcaps & VEX_HWCAPS_PPC32_VX)); allow_DFP = (0 != (hwcaps & VEX_HWCAPS_PPC32_DFP)); + allow_isa_2_07 = (0 != (hwcaps & VEX_HWCAPS_PPC32_ISA2_07)); } /* The running delta */ @@ -16928,8 +17049,9 @@ case 0x2B0: case 0x2F0: // xscvdpsxds, xscvsxddp case 0x1b0: case 0x130: // xvcvdpsxws, xvcvspsxws case 0x0b0: case 0x290: // xscvdpsxws, xscvdpuxds - case 0x212: // xscvdpsp - case 0x292: case 0x312: // xscvspdp, xvcvdpsp + case 0x212: case 0x216: // xscvdpsp, xscvdpspn + case 0x292: case 0x296: // xscvspdp, xscvspdpn + case 0x312: // xvcvdpsp case 0x390: case 0x190: // xvcvdpuxds, xvcvdpuxws case 0x3B0: case 0x310: // xvcvdpsxds, xvcvspuxds case 0x392: case 0x330: // xvcvspdp, xvcvspsxds @@ -16973,7 +17095,6 @@ /* 64bit Integer Stores */ case 0x3E: // std, stdu - if (!mode64) goto decode_failure; if (dis_int_store( theInstr, abiinfo )) goto decode_success; goto decode_failure; @@ -17008,7 +17129,7 @@ if (!allow_GX) goto decode_noGX; if (dis_fp_arith(theInstr)) goto decode_success; goto decode_failure; - + default: break; // Fall through } @@ -17358,6 +17479,8 @@ goto decode_failure; /* Processor Control Instructions */ + case 0x33: // mfvsrd + case 0xB3: case 0xD3: // mtvsrd, mtvsrwa case 0x200: case 0x013: case 0x153: // mcrxr, mfcr, mfspr case 0x173: case 0x090: case 0x1D3: // mftb, mtcrf, mtspr if (dis_proc_ctl( abiinfo, theInstr )) goto decode_success; @@ -17564,6 +17687,11 @@ if (dis_av_arith( theInstr )) goto decode_success; goto decode_failure; + case 0x0C0: // vaddudm + if (!allow_isa_2_07) goto decode_noP8; + if (dis_av_arith( theInstr )) goto decode_success; + goto decode_failure; + /* AV Rotate, Shift */ case 0x004: case 0x044: case 0x084: // vrlb, vrlh, vrlw case 0x104: case 0x144: case 0x184: // vslb, vslh, vslw @@ -17627,6 +17755,11 @@ if (dis_av_pack( theInstr )) goto decode_success; goto decode_failure; + case 0x44E: // vpkudum + if (!allow_isa_2_07) goto decode_noP8; + if (dis_av_pack( theInstr )) goto decode_success; + goto decode_failure; + default: break; // Fall through... } @@ -17684,6 +17817,11 @@ vex_printf("disInstr(ppc): " "declined to decode a Decimal Floating Point insn.\n"); goto decode_failure; + decode_noP8: + vassert(!allow_isa_2_07); + vex_printf("disInstr(ppc): " + "declined to decode a Power 8 insn.\n"); + goto decode_failure; decode_failure: @@ -17772,10 +17910,11 @@ /* do some sanity checks */ mask32 = VEX_HWCAPS_PPC32_F | VEX_HWCAPS_PPC32_V | VEX_HWCAPS_PPC32_FX | VEX_HWCAPS_PPC32_GX | VEX_HWCAPS_PPC32_VX - | VEX_HWCAPS_PPC32_DFP; + | VEX_HWCAPS_PPC32_DFP | VEX_HWCAPS_PPC32_ISA2_07; mask64 = VEX_HWCAPS_PPC64_V | VEX_HWCAPS_PPC64_FX - | VEX_HWCAPS_PPC64_GX | VEX_HWCAPS_PPC64_VX | VEX_HWCAPS_PPC64_DFP; + | VEX_HWCAPS_PPC64_GX | VEX_HWCAPS_PPC64_VX | VEX_HWCAPS_PPC64_DFP + | VEX_HWCAPS_PPC64_ISA2_07; if (mode64) { vassert((hwcaps_guest & mask32) == 0); diff -ur valgrind-3.8.1.orig/VEX/priv/host_ppc_defs.c valgrind-3.8.1/VEX/priv/host_ppc_defs.c --- valgrind-3.8.1.orig/VEX/priv/host_ppc_defs.c 2013-08-13 13:07:12.726887180 +0200 +++ valgrind-3.8.1/VEX/priv/host_ppc_defs.c 2013-08-13 13:10:17.466218906 +0200 @@ -674,7 +674,7 @@ case Pav_UNPCKLPIX: return "vupklpx"; /* Integer binary */ - case Pav_ADDU: return "vaddu_m"; // b,h,w + case Pav_ADDU: return "vaddu_m"; // b,h,w,dw case Pav_QADDU: return "vaddu_s"; // b,h,w case Pav_QADDS: return "vadds_s"; // b,h,w @@ -708,7 +708,7 @@ case Pav_ROTL: return "vrl"; // b,h,w /* Pack */ - case Pav_PACKUU: return "vpku_um"; // h,w + case Pav_PACKUU: return "vpku_um"; // h,w,dw case Pav_QPACKUU: return "vpku_us"; // h,w case Pav_QPACKSU: return "vpks_us"; // h,w case Pav_QPACKSS: return "vpks_ss"; // h,w @@ -1346,6 +1346,17 @@ i->Pin.AvBin32x4.srcR = srcR; return i; } +PPCInstr* PPCInstr_AvBin64x2 ( PPCAvOp op, HReg dst, + HReg srcL, HReg srcR ) { + PPCInstr* i = LibVEX_Alloc(sizeof(PPCInstr)); + i->tag = Pin_AvBin64x2; + i->Pin.AvBin64x2.op = op; + i->Pin.AvBin64x2.dst = dst; + i->Pin.AvBin64x2.srcL = srcL; + i->Pin.AvBin64x2.srcR = srcR; + return i; +} + PPCInstr* PPCInstr_AvBin32Fx4 ( PPCAvFpOp op, HReg dst, HReg srcL, HReg srcR ) { PPCInstr* i = LibVEX_Alloc(sizeof(PPCInstr)); @@ -1879,6 +1890,14 @@ vex_printf(","); ppHRegPPC(i->Pin.AvBin32x4.srcR); return; + case Pin_AvBin64x2: + vex_printf("%s(w) ", showPPCAvOp(i->Pin.AvBin64x2.op)); + ppHRegPPC(i->Pin.AvBin64x2.dst); + vex_printf(","); + ppHRegPPC(i->Pin.AvBin64x2.srcL); + vex_printf(","); + ppHRegPPC(i->Pin.AvBin64x2.srcR); + return; case Pin_AvBin32Fx4: vex_printf("%s ", showPPCAvFpOp(i->Pin.AvBin32Fx4.op)); ppHRegPPC(i->Pin.AvBin32Fx4.dst); @@ -2360,6 +2379,11 @@ addHRegUse(u, HRmRead, i->Pin.AvBin32x4.srcL); addHRegUse(u, HRmRead, i->Pin.AvBin32x4.srcR); return; + case Pin_AvBin64x2: + addHRegUse(u, HRmWrite, i->Pin.AvBin64x2.dst); + addHRegUse(u, HRmRead, i->Pin.AvBin64x2.srcL); + addHRegUse(u, HRmRead, i->Pin.AvBin64x2.srcR); + return; case Pin_AvBin32Fx4: addHRegUse(u, HRmWrite, i->Pin.AvBin32Fx4.dst); addHRegUse(u, HRmRead, i->Pin.AvBin32Fx4.srcL); @@ -2666,6 +2690,11 @@ mapReg(m, &i->Pin.AvBin32x4.srcL); mapReg(m, &i->Pin.AvBin32x4.srcR); return; + case Pin_AvBin64x2: + mapReg(m, &i->Pin.AvBin64x2.dst); + mapReg(m, &i->Pin.AvBin64x2.srcL); + mapReg(m, &i->Pin.AvBin64x2.srcR); + return; case Pin_AvBin32Fx4: mapReg(m, &i->Pin.AvBin32Fx4.dst); mapReg(m, &i->Pin.AvBin32Fx4.srcL); @@ -4771,6 +4800,24 @@ goto done; } + case Pin_AvBin64x2: { + UInt v_dst = vregNo(i->Pin.AvBin64x2.dst); + UInt v_srcL = vregNo(i->Pin.AvBin64x2.srcL); + UInt v_srcR = vregNo(i->Pin.AvBin64x2.srcR); + UInt opc2; + switch (i->Pin.AvBin64x2.op) { + case Pav_ADDU: opc2 = 192; break; // vaddudm vector double add + case Pav_PACKUU: opc2 = 1102; break; // vpkudum + // FIXME: We currently don't have a vector compare equal double word, so it's a hack + // to use vcmpequw, but it works. + case Pav_CMPEQU: opc2 = 134; break; // vcmpequw + default: + goto bad; + } + p = mkFormVX( p, 4, v_dst, v_srcL, v_srcR, opc2 ); + goto done; + } + case Pin_AvBin32Fx4: { UInt v_dst = vregNo(i->Pin.AvBin32Fx4.dst); UInt v_srcL = vregNo(i->Pin.AvBin32Fx4.srcL); diff -ur valgrind-3.8.1.orig/VEX/priv/host_ppc_defs.h valgrind-3.8.1/VEX/priv/host_ppc_defs.h --- valgrind-3.8.1.orig/VEX/priv/host_ppc_defs.h 2013-08-13 13:07:12.724887166 +0200 +++ valgrind-3.8.1/VEX/priv/host_ppc_defs.h 2013-08-13 13:10:17.469218928 +0200 @@ -488,6 +488,7 @@ Pin_AvBin8x16, /* AV binary, 8x4 */ Pin_AvBin16x8, /* AV binary, 16x4 */ Pin_AvBin32x4, /* AV binary, 32x4 */ + Pin_AvBin64x2, /* AV binary, 64x2 */ Pin_AvBin32Fx4, /* AV FP binary, 32Fx4 */ Pin_AvUn32Fx4, /* AV FP unary, 32Fx4 */ @@ -790,6 +791,13 @@ HReg srcL; HReg srcR; } AvBin32x4; + /* Can only be generated for CPUs capable of ISA 2.07 or above */ + struct { + PPCAvOp op; + HReg dst; + HReg srcL; + HReg srcR; + } AvBin64x2; struct { PPCAvFpOp op; HReg dst; @@ -1008,6 +1016,7 @@ extern PPCInstr* PPCInstr_AvBin8x16 ( PPCAvOp op, HReg dst, HReg srcL, HReg srcR ); extern PPCInstr* PPCInstr_AvBin16x8 ( PPCAvOp op, HReg dst, HReg srcL, HReg srcR ); extern PPCInstr* PPCInstr_AvBin32x4 ( PPCAvOp op, HReg dst, HReg srcL, HReg srcR ); +extern PPCInstr* PPCInstr_AvBin64x2 ( PPCAvOp op, HReg dst, HReg srcL, HReg srcR ); extern PPCInstr* PPCInstr_AvBin32Fx4 ( PPCAvFpOp op, HReg dst, HReg srcL, HReg srcR ); extern PPCInstr* PPCInstr_AvUn32Fx4 ( PPCAvFpOp op, HReg dst, HReg src ); extern PPCInstr* PPCInstr_AvPerm ( HReg dst, HReg srcL, HReg srcR, HReg ctl ); diff -ur valgrind-3.8.1.orig/VEX/priv/host_ppc_isel.c valgrind-3.8.1/VEX/priv/host_ppc_isel.c --- valgrind-3.8.1.orig/VEX/priv/host_ppc_isel.c 2013-08-13 13:07:12.732887222 +0200 +++ valgrind-3.8.1/VEX/priv/host_ppc_isel.c 2013-08-13 13:10:17.474218963 +0200 @@ -4325,6 +4325,16 @@ return dst; } + case Iop_CmpNEZ64x2: { + HReg arg = iselVecExpr(env, e->Iex.Unop.arg); + HReg zero = newVRegV(env); + HReg dst = newVRegV(env); + addInstr(env, PPCInstr_AvBinary(Pav_XOR, zero, zero, zero)); + addInstr(env, PPCInstr_AvBin64x2(Pav_CMPEQU, dst, arg, zero)); + addInstr(env, PPCInstr_AvUnary(Pav_NOT, dst, dst)); + return dst; + } + case Iop_Recip32Fx4: fpop = Pavfp_RCPF; goto do_32Fx4_unary; case Iop_RSqrt32Fx4: fpop = Pavfp_RSQRTF; goto do_32Fx4_unary; case Iop_I32UtoFx4: fpop = Pavfp_CVTU2F; goto do_32Fx4_unary; @@ -4589,6 +4599,16 @@ return dst; } + case Iop_NarrowBin64to32x4: op = Pav_PACKUU; goto do_AvBin64x2; + case Iop_Add64x2: op = Pav_ADDU; goto do_AvBin64x2; + do_AvBin64x2: { + HReg arg1 = iselVecExpr(env, e->Iex.Binop.arg1); + HReg arg2 = iselVecExpr(env, e->Iex.Binop.arg2); + HReg dst = newVRegV(env); + addInstr(env, PPCInstr_AvBin64x2(op, dst, arg1, arg2)); + return dst; + } + case Iop_ShlN8x16: op = Pav_SHL; goto do_AvShift8x16; case Iop_SarN8x16: op = Pav_SAR; goto do_AvShift8x16; do_AvShift8x16: { @@ -5233,10 +5253,12 @@ /* do some sanity checks */ mask32 = VEX_HWCAPS_PPC32_F | VEX_HWCAPS_PPC32_V | VEX_HWCAPS_PPC32_FX | VEX_HWCAPS_PPC32_GX | VEX_HWCAPS_PPC32_VX - | VEX_HWCAPS_PPC32_DFP; + | VEX_HWCAPS_PPC32_DFP | VEX_HWCAPS_PPC32_ISA2_07; + mask64 = VEX_HWCAPS_PPC64_V | VEX_HWCAPS_PPC64_FX - | VEX_HWCAPS_PPC64_GX | VEX_HWCAPS_PPC64_VX | VEX_HWCAPS_PPC64_DFP; + | VEX_HWCAPS_PPC64_GX | VEX_HWCAPS_PPC64_VX | VEX_HWCAPS_PPC64_DFP + | VEX_HWCAPS_PPC64_ISA2_07; if (mode64) { vassert((hwcaps_host & mask32) == 0); diff -ur valgrind-3.8.1.orig/VEX/priv/ir_defs.c valgrind-3.8.1/VEX/priv/ir_defs.c --- valgrind-3.8.1.orig/VEX/priv/ir_defs.c 2013-08-13 13:07:12.728887194 +0200 +++ valgrind-3.8.1/VEX/priv/ir_defs.c 2013-08-13 13:10:17.477218984 +0200 @@ -523,6 +523,7 @@ case Iop_QNarrowBin32Sto16Sx4: vex_printf("QNarrowBin32Sto16Sx4"); return; case Iop_NarrowBin16to8x8: vex_printf("NarrowBin16to8x8"); return; case Iop_NarrowBin32to16x4: vex_printf("NarrowBin32to16x4"); return; + case Iop_NarrowBin64to32x4: vex_printf("NarrowBin64to32x4"); return; case Iop_InterleaveHI8x8: vex_printf("InterleaveHI8x8"); return; case Iop_InterleaveHI16x4: vex_printf("InterleaveHI16x4"); return; case Iop_InterleaveHI32x2: vex_printf("InterleaveHI32x2"); return; @@ -2650,6 +2651,7 @@ case Iop_QNarrowBin16Sto8Sx16: case Iop_QNarrowBin32Sto16Sx8: case Iop_QNarrowBin16Uto8Ux16: case Iop_QNarrowBin32Uto16Ux8: case Iop_NarrowBin16to8x16: case Iop_NarrowBin32to16x8: + case Iop_NarrowBin64to32x4: case Iop_InterleaveHI8x16: case Iop_InterleaveHI16x8: case Iop_InterleaveHI32x4: case Iop_InterleaveHI64x2: case Iop_InterleaveLO8x16: case Iop_InterleaveLO16x8: diff -ur valgrind-3.8.1.orig/VEX/priv/main_main.c valgrind-3.8.1/VEX/priv/main_main.c --- valgrind-3.8.1.orig/VEX/priv/main_main.c 2013-08-13 13:07:12.732887222 +0200 +++ valgrind-3.8.1/VEX/priv/main_main.c 2013-08-13 13:10:17.479218998 +0200 @@ -1164,6 +1164,7 @@ const UInt GX = VEX_HWCAPS_PPC32_GX; const UInt VX = VEX_HWCAPS_PPC32_VX; const UInt DFP = VEX_HWCAPS_PPC32_DFP; + const UInt ISA2_07 = VEX_HWCAPS_PPC32_ISA2_07; UInt c = hwcaps; if (c == 0) return "ppc32-int"; if (c == F) return "ppc32-int-flt"; @@ -1176,6 +1177,9 @@ if (c == (F|V|FX|GX)) return "ppc32-int-flt-vmx-FX-GX"; if (c == (F|V|FX|GX|DFP)) return "ppc32-int-flt-vmx-FX-GX-DFP"; if (c == (F|V|FX|GX|VX|DFP)) return "ppc32-int-flt-vmx-FX-GX-VX-DFP"; + if (c == (F|V|FX|GX|VX|DFP|ISA2_07)) + return "ppc32-int-flt-vmx-FX-GX-VX-DFP-ISA2_07"; + return NULL; } @@ -1188,6 +1192,7 @@ const UInt GX = VEX_HWCAPS_PPC64_GX; const UInt VX = VEX_HWCAPS_PPC64_VX; const UInt DFP = VEX_HWCAPS_PPC64_DFP; + const UInt ISA2_07 = VEX_HWCAPS_PPC64_ISA2_07; UInt c = hwcaps; if (c == 0) return "ppc64-int-flt"; if (c == FX) return "ppc64-int-flt-FX"; @@ -1199,6 +1204,8 @@ if (c == (V|FX|GX)) return "ppc64-int-flt-vmx-FX-GX"; if (c == (V|FX|GX|DFP)) return "ppc64-int-flt-vmx-FX-GX-DFP"; if (c == (V|FX|GX|VX|DFP)) return "ppc64-int-flt-vmx-FX-GX-VX-DFP"; + if (c == (V|FX|GX|VX|DFP|ISA2_07)) + return "ppc64-int-flt-vmx-FX-GX-VX-DFP-ISA2_07"; return NULL; } diff -ur valgrind-3.8.1.orig/VEX/pub/libvex.h valgrind-3.8.1/VEX/pub/libvex.h --- valgrind-3.8.1.orig/VEX/pub/libvex.h 2013-08-13 13:07:12.724887166 +0200 +++ valgrind-3.8.1/VEX/pub/libvex.h 2013-08-13 13:10:17.481219013 +0200 @@ -93,6 +93,7 @@ (fres,frsqrte,fsel,stfiwx) */ #define VEX_HWCAPS_PPC32_VX (1<<12) /* Vector-scalar floating-point (VSX); implies ISA 2.06 or higher */ #define VEX_HWCAPS_PPC32_DFP (1<<17) /* Decimal Floating Point (DFP) -- e.g., dadd */ +#define VEX_HWCAPS_PPC32_ISA2_07 (1<<19) /* ISA 2.07 -- e.g., mtvsrd */ /* ppc64: baseline capability is integer and basic FP insns */ #define VEX_HWCAPS_PPC64_V (1<<13) /* Altivec (VMX) */ @@ -101,6 +102,7 @@ (fres,frsqrte,fsel,stfiwx) */ #define VEX_HWCAPS_PPC64_VX (1<<16) /* Vector-scalar floating-point (VSX); implies ISA 2.06 or higher */ #define VEX_HWCAPS_PPC64_DFP (1<<18) /* Decimal Floating Point (DFP) -- e.g., dadd */ +#define VEX_HWCAPS_PPC64_ISA2_07 (1<<20) /* ISA 2.07 -- e.g., mtvsrd */ /* s390x: Hardware capability encoding diff -ur valgrind-3.8.1.orig/VEX/pub/libvex_ir.h valgrind-3.8.1/VEX/pub/libvex_ir.h --- valgrind-3.8.1.orig/VEX/pub/libvex_ir.h 2013-08-13 13:07:12.724887166 +0200 +++ valgrind-3.8.1/VEX/pub/libvex_ir.h 2013-08-13 13:10:17.482219021 +0200 @@ -1354,6 +1354,7 @@ Iop_QNarrowBin16Sto8Sx16, Iop_QNarrowBin32Sto16Sx8, Iop_QNarrowBin16Uto8Ux16, Iop_QNarrowBin32Uto16Ux8, Iop_NarrowBin16to8x16, Iop_NarrowBin32to16x8, + Iop_NarrowBin64to32x4, /* NARROWING (unary) -- narrow V128 into I64 */ Iop_NarrowUn16to8x8, Iop_NarrowUn32to16x4, Iop_NarrowUn64to32x2, diff --git a/none/tests/ppc32/jm_vec_isa_2_07.stderr.exp b/none/tests/ppc32/jm_vec_isa_2_07.stderr.exp new file mode 100644 index 0000000..139597f --- /dev/null +++ b/none/tests/ppc32/jm_vec_isa_2_07.stderr.exp @@ -0,0 +1,2 @@ + + diff --git a/none/tests/ppc32/jm_vec_isa_2_07.stdout.exp b/none/tests/ppc32/jm_vec_isa_2_07.stdout.exp new file mode 100644 index 0000000..a2d83e6 --- /dev/null +++ b/none/tests/ppc32/jm_vec_isa_2_07.stdout.exp @@ -0,0 +1,34 @@ +mfvsrd: 0102030405060708 => 0000000005060708 +mfvsrd: 090a0b0c0e0d0e0f => 000000000e0d0e0f +mfvsrd: f1f2f3f4f5f6f7f8 => 00000000f5f6f7f8 +mfvsrd: f9fafbfcfefdfeff => 00000000fefdfeff + +mtvsrd: 0102030405060708 => 0000000005060708 +mtvsrd: 090a0b0c0e0d0e0f => 000000000e0d0e0f +mtvsrd: f1f2f3f4f5f6f7f8 => 00000000f5f6f7f8 +mtvsrd: f9fafbfcfefdfeff => 00000000fefdfeff + +mtfprwa: 05060708 => 0000000005060708 +mtfprwa: 0e0d0e0f => 000000000e0d0e0f +mtfprwa: f5f6f7f8 => fffffffff5f6f7f8 +mtfprwa: fefdfeff => fffffffffefdfeff + +vaddudm: 0102030405060708 @@ 0102030405060708, ==> 020406080a0c0e10 + 090a0b0c0e0d0e0f @@ 090a0b0c0e0d0e0f, ==> 121416181c1a1c1e +vaddudm: 0102030405060708 @@ f1f2f3f4f5f6f7f8, ==> f2f4f6f8fafcff00 + 090a0b0c0e0d0e0f @@ f9fafbfcfefdfeff, ==> 030507090d0b0d0e +vaddudm: f1f2f3f4f5f6f7f8 @@ 0102030405060708, ==> f2f4f6f8fafcff00 + f9fafbfcfefdfeff @@ 090a0b0c0e0d0e0f, ==> 030507090d0b0d0e +vaddudm: f1f2f3f4f5f6f7f8 @@ f1f2f3f4f5f6f7f8, ==> e3e5e7e9ebedeff0 + f9fafbfcfefdfeff @@ f9fafbfcfefdfeff, ==> f3f5f7f9fdfbfdfe + +vpkudum: Inputs: 05060708 0e0d0e0f 05060708 0e0d0e0f + Output: 05060708 0e0d0e0f 05060708 0e0d0e0f +vpkudum: Inputs: 05060708 0e0d0e0f f5f6f7f8 fefdfeff + Output: 05060708 0e0d0e0f f5f6f7f8 fefdfeff +vpkudum: Inputs: f5f6f7f8 fefdfeff 05060708 0e0d0e0f + Output: f5f6f7f8 fefdfeff 05060708 0e0d0e0f +vpkudum: Inputs: f5f6f7f8 fefdfeff f5f6f7f8 fefdfeff + Output: f5f6f7f8 fefdfeff f5f6f7f8 fefdfeff + +All done. Tested 5 different instructions diff --git a/none/tests/ppc32/jm_vec_isa_2_07.vgtest b/none/tests/ppc32/jm_vec_isa_2_07.vgtest new file mode 100644 index 0000000..a93060a --- /dev/null +++ b/none/tests/ppc32/jm_vec_isa_2_07.vgtest @@ -0,0 +1,2 @@ +prereq: ../../../tests/check_isa-2_07_cap +prog: test_isa_2_07_part1 -a diff --git a/none/tests/ppc32/test_isa_2_07_part1.c b/none/tests/ppc32/test_isa_2_07_part1.c new file mode 120000 index 0000000..b258517 --- /dev/null +++ b/none/tests/ppc32/test_isa_2_07_part1.c @@ -0,0 +1 @@ +../ppc64/test_isa_2_07_part1.c \ No newline at end of file diff --git a/none/tests/ppc32/test_isa_2_07_part2.c b/none/tests/ppc32/test_isa_2_07_part2.c new file mode 120000 index 0000000..3eb5caf --- /dev/null +++ b/none/tests/ppc32/test_isa_2_07_part2.c @@ -0,0 +1 @@ +../ppc64/test_isa_2_07_part2.c \ No newline at end of file diff --git a/none/tests/ppc32/test_isa_2_07_part2.stderr.exp b/none/tests/ppc32/test_isa_2_07_part2.stderr.exp new file mode 100644 index 0000000..139597f --- /dev/null +++ b/none/tests/ppc32/test_isa_2_07_part2.stderr.exp @@ -0,0 +1,2 @@ + + diff --git a/none/tests/ppc32/test_isa_2_07_part2.stdout.exp b/none/tests/ppc32/test_isa_2_07_part2.stdout.exp new file mode 100644 index 0000000..c65c574 --- /dev/null +++ b/none/tests/ppc32/test_isa_2_07_part2.stdout.exp @@ -0,0 +1,44 @@ +Test VSX vector and scalar single argument instructions +#0: xscvdpspn conv(3fd8000000000000) = 3ec0000000000000 +#1: xscvdpspn conv(404f000000000000) = 4278000000000000 +#2: xscvdpspn conv(0018000000b77501) = 0000000000000000 +#3: xscvdpspn conv(7fe800000000051b) = 7f40000000000000 +#4: xscvdpspn conv(0123214569900000) = 0000000000000000 +#5: xscvdpspn conv(0000000000000000) = 0000000000000000 +#6: xscvdpspn conv(8000000000000000) = 8000000000000000 +#7: xscvdpspn conv(7ff0000000000000) = 7f80000000000000 +#8: xscvdpspn conv(fff0000000000000) = ff80000000000000 +#9: xscvdpspn conv(7ff7ffffffffffff) = 7fbfffff00000000 +#10: xscvdpspn conv(fff7ffffffffffff) = ffbfffff00000000 +#11: xscvdpspn conv(7ff8000000000000) = 7fc0000000000000 +#12: xscvdpspn conv(fff8000000000000) = ffc0000000000000 +#13: xscvdpspn conv(8008340000078000) = 8000000000000000 +#14: xscvdpspn conv(c0d0650f5a07b353) = c683287a00000000 +#15: xscvdpspn conv(41232585a9900000) = 49192c2d00000000 +#16: xscvdpspn conv(41382511a2000000) = 49c1288d00000000 +#17: xscvdpspn conv(40312ef5a9300000) = 418977ad00000000 +#18: xscvdpspn conv(40514bf5d2300000) = 428a5fae00000000 +#19: xscvdpspn conv(40976bf982440000) = 44bb5fcc00000000 + +#0: xscvspdpn conv(3ec00000) = 3fd8000000000000 +#1: xscvspdpn conv(42780000) = 404f000000000000 +#2: xscvspdpn conv(00000000) = 0000000000000000 +#3: xscvspdpn conv(7f800000) = 7ff0000000000000 +#4: xscvspdpn conv(00000000) = 0000000000000000 +#5: xscvspdpn conv(00000000) = 0000000000000000 +#6: xscvspdpn conv(80000000) = 8000000000000000 +#7: xscvspdpn conv(7f800000) = 7ff0000000000000 +#8: xscvspdpn conv(ff800000) = fff0000000000000 +#9: xscvspdpn conv(7fffffff) = 7fffffffe0000000 +#10: xscvspdpn conv(ffffffff) = ffffffffe0000000 +#11: xscvspdpn conv(7fc00000) = 7ff8000000000000 +#12: xscvspdpn conv(ffc00000) = fff8000000000000 +#13: xscvspdpn conv(80000000) = 8000000000000000 +#14: xscvspdpn conv(c683287b) = c0d0650f60000000 +#15: xscvspdpn conv(49192c2d) = 41232585a0000000 +#16: xscvspdpn conv(49c1288d) = 41382511a0000000 +#17: xscvspdpn conv(418977ad) = 40312ef5a0000000 +#18: xscvspdpn conv(428a5faf) = 40514bf5e0000000 +#19: xscvspdpn conv(44bb5fcc) = 40976bf980000000 + +Testcase PASSED diff --git a/none/tests/ppc32/test_isa_2_07_part2.vgtest b/none/tests/ppc32/test_isa_2_07_part2.vgtest new file mode 100644 index 0000000..a4649be --- /dev/null +++ b/none/tests/ppc32/test_isa_2_07_part2.vgtest @@ -0,0 +1,2 @@ +prereq: ../../../tests/check_isa-2_07_cap +prog: test_isa_2_07_part2 diff --git a/none/tests/ppc64/jm_vec_isa_2_07.stderr.exp b/none/tests/ppc64/jm_vec_isa_2_07.stderr.exp new file mode 100755 index 0000000..139597f --- /dev/null +++ b/none/tests/ppc64/jm_vec_isa_2_07.stderr.exp @@ -0,0 +1,2 @@ + + diff --git a/none/tests/ppc64/jm_vec_isa_2_07.stdout.exp b/none/tests/ppc64/jm_vec_isa_2_07.stdout.exp new file mode 100644 index 0000000..2568739 --- /dev/null +++ b/none/tests/ppc64/jm_vec_isa_2_07.stdout.exp @@ -0,0 +1,34 @@ +mfvsrd: 0102030405060708 => 0102030405060708 +mfvsrd: 090a0b0c0e0d0e0f => 090a0b0c0e0d0e0f +mfvsrd: f1f2f3f4f5f6f7f8 => f1f2f3f4f5f6f7f8 +mfvsrd: f9fafbfcfefdfeff => f9fafbfcfefdfeff + +mtvsrd: 0102030405060708 => 0102030405060708 +mtvsrd: 090a0b0c0e0d0e0f => 090a0b0c0e0d0e0f +mtvsrd: f1f2f3f4f5f6f7f8 => f1f2f3f4f5f6f7f8 +mtvsrd: f9fafbfcfefdfeff => f9fafbfcfefdfeff + +mtfprwa: 05060708 => 0000000005060708 +mtfprwa: 0e0d0e0f => 000000000e0d0e0f +mtfprwa: f5f6f7f8 => fffffffff5f6f7f8 +mtfprwa: fefdfeff => fffffffffefdfeff + +vaddudm: 0102030405060708 @@ 0102030405060708, ==> 020406080a0c0e10 + 090a0b0c0e0d0e0f @@ 090a0b0c0e0d0e0f, ==> 121416181c1a1c1e +vaddudm: 0102030405060708 @@ f1f2f3f4f5f6f7f8, ==> f2f4f6f8fafcff00 + 090a0b0c0e0d0e0f @@ f9fafbfcfefdfeff, ==> 030507090d0b0d0e +vaddudm: f1f2f3f4f5f6f7f8 @@ 0102030405060708, ==> f2f4f6f8fafcff00 + f9fafbfcfefdfeff @@ 090a0b0c0e0d0e0f, ==> 030507090d0b0d0e +vaddudm: f1f2f3f4f5f6f7f8 @@ f1f2f3f4f5f6f7f8, ==> e3e5e7e9ebedeff0 + f9fafbfcfefdfeff @@ f9fafbfcfefdfeff, ==> f3f5f7f9fdfbfdfe + +vpkudum: Inputs: 05060708 0e0d0e0f 05060708 0e0d0e0f + Output: 05060708 0e0d0e0f 05060708 0e0d0e0f +vpkudum: Inputs: 05060708 0e0d0e0f f5f6f7f8 fefdfeff + Output: 05060708 0e0d0e0f f5f6f7f8 fefdfeff +vpkudum: Inputs: f5f6f7f8 fefdfeff 05060708 0e0d0e0f + Output: f5f6f7f8 fefdfeff 05060708 0e0d0e0f +vpkudum: Inputs: f5f6f7f8 fefdfeff f5f6f7f8 fefdfeff + Output: f5f6f7f8 fefdfeff f5f6f7f8 fefdfeff + +All done. Tested 5 different instructions diff --git a/none/tests/ppc64/jm_vec_isa_2_07.vgtest b/none/tests/ppc64/jm_vec_isa_2_07.vgtest new file mode 100644 index 0000000..a93060a --- /dev/null +++ b/none/tests/ppc64/jm_vec_isa_2_07.vgtest @@ -0,0 +1,2 @@ +prereq: ../../../tests/check_isa-2_07_cap +prog: test_isa_2_07_part1 -a diff --git a/none/tests/ppc64/test_isa_2_07_part1.c b/none/tests/ppc64/test_isa_2_07_part1.c new file mode 100644 index 0000000..8606c62 --- /dev/null +++ b/none/tests/ppc64/test_isa_2_07_part1.c @@ -0,0 +1,746 @@ + +/* HOW TO COMPILE: + + * 32bit build: + gcc -Winline -Wall -g -O -mregnames -maltivec + * 64bit build: + gcc -Winline -Wall -g -O -mregnames -maltivec -m64 + + + * jm_insns_isa_2_07.c: + * PPC tests for the ISA 2.07. This file is based on the + * jm-insns.c file for the new instructions in the ISA 2.07. The + * test structure has been kept the same as the original file to + * the extent possible. + * + * Copyright (C) 2013 IBM + * + * Authors: Carl Love + * Maynard Johnson + * + * 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 + * + */ + +/* + * Operation details + * ----------------- + * + * The 'loops' (e.g. int_loops) do the actual work: + * - loops over as many arguments as the insn needs (regs | imms) + * - sets up the environment (reset cr,xer, assign src regs...) + * - maybe modifies the asm instn to test different imm args + * - calls the test function + * - retrieves relevant register data (rD,cr,xer,...) + * - prints argument and result data. + * + * More specifically... + * + * all_tests[i] holds insn tests + * - of which each holds: {instn_test_arr[], description, flags} + * + * flags hold 3 instn classifiers: {family, type, arg_type} + * + * // The main test loop: + * do_tests( user_ctl_flags ) { + * foreach(curr_test = all_test[i]) { + * + * // flags are used to control what tests are run: + * if (curr_test->flags && !user_ctl_flags) + * continue; + * + * // a 'loop_family_arr' is chosen based on the 'family' flag... + * switch(curr_test->flags->family) { + * case x: loop_family_arr = int_loops; + * ... + * } + * + * // ...and the actual test_loop to run is found by indexing into + * // the loop_family_arr with the 'arg_type' flag: + * test_loop = loop_family[curr_test->flags->arg_type] + * + * // finally, loop over all instn tests for this test: + * foreach (instn_test = curr_test->instn_test_arr[i]) { + * + * // and call the test_loop with the current instn_test function,name + * test_loop( instn_test->func, instn_test->name ) + * } + * } + * } + * + */ + + +/**********************************************************************/ + +/* Uncomment to enable output of CR flags for float tests */ +//#define TEST_FLOAT_FLAGS + +/* Uncomment to enable debug output */ +//#define DEBUG_ARGS_BUILD +//#define DEBUG_FILTER + +/**********************************************************************/ +#include + +#ifdef HAS_ISA_2_07 + +#include "config.h" +#include +#include + +#include +#include // isspace +#include +#include +#include // getopt + +#if !defined (__TEST_PPC_H__) +#define __TEST_PPC_H__ + +#include "tests/sys_mman.h" +#include "tests/malloc.h" // memalign16 + +#define STATIC_ASSERT(e) sizeof(struct { int:-!(e); }) + +/* Something of the same size as void*, so can be safely be coerced + * to/from a pointer type. Also same size as the host's gp registers. + * According to the AltiVec section of the GCC manual, the syntax does + * not allow the use of a typedef name as a type specifier in conjunction + * with the vector keyword, so typedefs uint[32|64]_t are #undef'ed here + * and redefined using #define. + */ +#undef uint32_t +#undef uint64_t +#define uint32_t unsigned int +#define uint64_t unsigned long long int + +#ifndef __powerpc64__ +typedef uint32_t HWord_t; +#else +typedef uint64_t HWord_t; +#endif /* __powerpc64__ */ + +typedef uint64_t Word_t; + +enum { + compile_time_test1 = STATIC_ASSERT(sizeof(uint32_t) == 4), + compile_time_test2 = STATIC_ASSERT(sizeof(uint64_t) == 8), +}; + +#define ALLCR "cr0","cr1","cr2","cr3","cr4","cr5","cr6","cr7" + +#define SET_CR(_arg) \ + __asm__ __volatile__ ("mtcr %0" : : "b"(_arg) : ALLCR ); + +#define SET_XER(_arg) \ + __asm__ __volatile__ ("mtxer %0" : : "b"(_arg) : "xer" ); + +#define GET_CR(_lval) \ + __asm__ __volatile__ ("mfcr %0" : "=b"(_lval) ) + +#define GET_XER(_lval) \ + __asm__ __volatile__ ("mfxer %0" : "=b"(_lval) ) + +#define GET_CR_XER(_lval_cr,_lval_xer) \ + do { GET_CR(_lval_cr); GET_XER(_lval_xer); } while (0) + +#define SET_CR_ZERO \ + SET_CR(0) + +#define SET_XER_ZERO \ + SET_XER(0) + +#define SET_CR_XER_ZERO \ + do { SET_CR_ZERO; SET_XER_ZERO; } while (0) + +#define SET_FPSCR_ZERO \ + do { double _d = 0.0; \ + __asm__ __volatile__ ("mtfsf 0xFF, %0" : : "f"(_d) ); \ + } while (0) + +#define DEFAULT_VSCR 0x0 + +static vector unsigned long long vec_out, vec_inA, vec_inB; + +/* XXXX these must all be callee-save regs! */ +register double f14 __asm__ ("fr14"); +register double f15 __asm__ ("fr15"); +register double f16 __asm__ ("fr16"); +register double f17 __asm__ ("fr17"); +register HWord_t r14 __asm__ ("r14"); +register HWord_t r17 __asm__ ("r17"); + +typedef void (*test_func_t) (void); +typedef struct _test test_t; +typedef struct _test_table test_table_t; +struct _test { + test_func_t func; + const char *name; +}; + +struct _test_table { + test_t *tests; + const char *name; + uint32_t flags; +}; + +typedef void (*test_loop_t) (const char *name, test_func_t func, + uint32_t flags); + +enum test_flags { + /* Nb arguments */ + PPC_ONE_ARG = 0x00000001, + PPC_TWO_ARGS = 0x00000002, + PPC_THREE_ARGS = 0x00000003, + PPC_CMP_ARGS = 0x00000004, // family: compare + PPC_CMPI_ARGS = 0x00000005, // family: compare + PPC_TWO_I16 = 0x00000006, // family: arith/logical + PPC_SPECIAL = 0x00000007, // family: logical + PPC_LD_ARGS = 0x00000008, // family: ldst + PPC_LDX_ARGS = 0x00000009, // family: ldst + PPC_ST_ARGS = 0x0000000A, // family: ldst + PPC_STX_ARGS = 0x0000000B, // family: ldst + PPC_STQ_ARGS = 0x0000000C, // family: ldst, two args, imm + PPC_LDQ_ARGS = 0x0000000D, // family: ldst, two args, imm + PPC_STQX_ARGS = 0x0000000E, // family: ldst, three args + PPC_LDQX_ARGS = 0x0000000F, // family: ldst, three_args + PPC_NB_ARGS = 0x0000000F, + /* Type */ + PPC_ARITH = 0x00000100, + PPC_LOGICAL = 0x00000200, + PPC_COMPARE = 0x00000300, + PPC_CROP = 0x00000400, + PPC_LDST = 0x00000500, + PPC_POPCNT = 0x00000600, + PPC_MOV = 0x00000A00, + PPC_TYPE = 0x00000F00, + /* Family */ + PPC_INTEGER = 0x00010000, + PPC_FLOAT = 0x00020000, + PPC_405 = 0x00030000, // Leave so we keep numbering consistent + PPC_ALTIVEC = 0x00040000, + PPC_FALTIVEC = 0x00050000, + PPC_FAMILY = 0x000F0000, + /* Flags: these may be combined, so use separate bitfields. */ + PPC_CR = 0x01000000, + PPC_XER_CA = 0x02000000, +}; + +#endif /* !defined (__TEST_PPC_H__) */ + +/* -------------- END #include "test-ppc.h" -------------- */ + + +#if defined (DEBUG_ARGS_BUILD) +#define AB_DPRINTF(fmt, args...) do { fprintf(stderr, fmt , ##args); } while (0) +#else +#define AB_DPRINTF(fmt, args...) do { } while (0) +#endif + +#if defined (DEBUG_FILTER) +#define FDPRINTF(fmt, args...) do { fprintf(stderr, fmt , ##args); } while (0) +#else +#define FDPRINTF(fmt, args...) do { } while (0) +#endif + +#define unused __attribute__ (( unused )) + +typedef struct special { + const char *name; + void (*test_cb)(const char* name, test_func_t func, + unused uint32_t test_flags); +} special_t; + + +// VSX move instructions +static void test_mfvsrd (void) +{ + __asm__ __volatile__ ("mfvsrd %0,%x1" : "=r" (r14) : "ws" (vec_inA)); +}; + +static void test_mtvsrd (void) +{ + __asm__ __volatile__ ("mtvsrd %x0,%1" : "=ws" (vec_out) : "r" (r14)); +}; + +static void test_mtfprwa (void) +{ + __asm__ __volatile__ ("mtfprwa %x0,%1" : "=ws" (vec_out) : "r" (r14)); +}; + +static test_t tests_move_ops_spe[] = { + { &test_mfvsrd , "mfvsrd" }, + { &test_mtvsrd , "mtvsrd" }, + { &test_mtfprwa , "mtfprwa" }, + { NULL, NULL } +}; + +/* Vector Double Word tests. + * NOTE: Since these are "vector" instructions versus VSX, we must use + * vector constraints. */ +static void test_vaddudm (void) +{ + __asm__ __volatile__ ("vaddudm %0, %1, %2" : "=v" (vec_out): "v" (vec_inA),"v" (vec_inB)); +} + +static void test_vpkudum (void) +{ + __asm__ __volatile__ ("vpkudum %0, %1, %2" : "=v" (vec_out): "v" (vec_inA),"v" (vec_inB)); +} + +static test_t tests_aa_dbl_ops_two[] = { + { &test_vaddudm , "vaddudm", }, + { &test_vpkudum , "vpkudum", }, + { NULL, NULL, }, +}; + +static int verbose = 0; +static int arg_list_size = 0; +static unsigned long long * vdargs = NULL; +#define NB_VDARGS 4 + +static void build_vdargs_table (void) +{ + // Each VSX register holds two doubleword integer values + vdargs = memalign16(NB_VDARGS * sizeof(unsigned long long)); + vdargs[0] = 0x0102030405060708ULL; + vdargs[1] = 0x090A0B0C0E0D0E0FULL; + vdargs[2] = 0xF1F2F3F4F5F6F7F8ULL; + vdargs[3] = 0xF9FAFBFCFEFDFEFFULL; +} + +static int check_filter (char *filter) +{ + char *c; + int ret = 1; + + if (filter != NULL) { + c = strchr(filter, '*'); + if (c != NULL) { + *c = '\0'; + ret = 0; + } + } + return ret; +} + +static int check_name (const char* name, const char *filter, + int exact) +{ + int nlen, flen; + int ret = 0; + + if (filter != NULL) { + for (; isspace(*name); name++) + continue; + FDPRINTF("Check '%s' againt '%s' (%s match)\n", + name, filter, exact ? "exact" : "starting"); + nlen = strlen(name); + flen = strlen(filter); + if (exact) { + if (nlen == flen && memcmp(name, filter, flen) == 0) + ret = 1; + } else { + if (flen <= nlen && memcmp(name, filter, flen) == 0) + ret = 1; + } + } else { + ret = 1; + } + return ret; +} + + +typedef struct insn_sel_flags_t_struct { + int one_arg, two_args, three_args; + int arith, logical, compare, ldst; + int integer, floats, altivec, faltivec; + int cr; +} insn_sel_flags_t; + + +static void mfvs(const char* name, test_func_t func, + unused uint32_t test_flags) +{ + /* This test is for move instructions where the input is a scalar register + * and the destination is a vector register. + */ + int i; + volatile Word_t result; + + for (i=0; i < NB_VDARGS; i++) { + r14 = 0ULL; + vec_inA = (vector unsigned long long){ vdargs[i], 0ULL }; + + (*func)(); + result = r14; + printf("%s: %016llx => %016llx\n", name, vdargs[i], result); + } +} + +static void mtvs(const char* name, test_func_t func, + unused uint32_t test_flags) +{ + /* This test is for move instructions where the input is a scalar register + * and the destination is a vector register. + */ + unsigned long long *dst; + int i; + + for (i=0; i < NB_VDARGS; i++) { + r14 = vdargs[i]; + vec_out = (vector unsigned long long){ 0ULL, 0ULL }; + + (*func)(); + dst = (unsigned long long *) &vec_out; + printf("%s: %016llx => %016llx\n", name, vdargs[i], *dst); + } +} + +static void mtvs2s(const char* name, test_func_t func, + unused uint32_t test_flags) +{ + /* This test is the mtvsrwa instruction. + */ + unsigned long long *dst; + int i; + + for (i=0; i < NB_VDARGS; i++) { + // Only the lower half of the vdarg doubleword arg will be used as input by mtvsrwa + unsigned int * src = (unsigned int *)&vdargs[i]; + src++; + r14 = vdargs[i]; + vec_out = (vector unsigned long long){ 0ULL, 0ULL }; + + (*func)(); + // Only doubleword 0 is used in output + dst = (unsigned long long *) &vec_out; + printf("%s: %08x => %016llx\n", name, *src, *dst); + } +} + +static void test_special (special_t *table, + const char* name, test_func_t func, + unused uint32_t test_flags) +{ + const char *tmp; + int i; + + for (tmp = name; isspace(*tmp); tmp++) + continue; + for (i=0; table[i].name != NULL; i++) { + if (strcmp(table[i].name, tmp) == 0) { + (*table[i].test_cb)(name, func, test_flags); + return; + } + } + fprintf(stderr, "ERROR: no test found for op '%s'\n", name); +} + +static special_t special_move_ops[] = { + { + "mfvsrd", /* move from vector to scalar reg */ + &mfvs, + }, + { + "mtvsrd", /* move from scalar to vector reg */ + &mtvs, + }, + { + "mtfprwa", /* (extended mnemonic for mtvsrwa) move from scalar to vector reg with two’s-complement */ + &mtvs2s, + }, +}; + +static void test_move_special(const char* name, test_func_t func, + uint32_t test_flags) +{ + test_special(special_move_ops, name, func, test_flags); +} + +/* Vector Double Word tests */ + +static void test_av_dint_two_args (const char* name, test_func_t func, + unused uint32_t test_flags) +{ + + unsigned long long * dst; + unsigned int * dst_int; + int i,j; + int is_vpkudum; + if (strcmp(name, "vpkudum") == 0) + is_vpkudum = 1; + else + is_vpkudum = 0; + + for (i = 0; i < NB_VDARGS; i+=2) { + vec_inA = (vector unsigned long long){ vdargs[i], vdargs[i+1] }; + for (j = 0; j < NB_VDARGS; j+=2) { + vec_inB = (vector unsigned long long){ vdargs[j], vdargs[j+1] }; + vec_out = (vector unsigned long long){ 0,0 }; + + (*func)(); + dst_int = (unsigned int *)&vec_out; + dst = (unsigned long long*)&vec_out; + + printf("%s: ", name); + + if (is_vpkudum) { + printf("Inputs: %08llx %08llx %08llx %08llx\n", vdargs[i] & 0x00000000ffffffffULL, + vdargs[i+1] & 0x00000000ffffffffULL, vdargs[j] & 0x00000000ffffffffULL, + vdargs[j+1] & 0x00000000ffffffffULL); + printf(" Output: %08x %08x %08x %08x\n", dst_int[0], dst_int[1], + dst_int[2], dst_int[3]); + } else { + printf("%016llx @@ %016llx, ", vdargs[i], vdargs[j]); + printf(" ==> %016llx\n", dst[0]); + printf("\t%016llx @@ %016llx, ", vdargs[i+1], vdargs[j+1]); + printf(" ==> %016llx\n", dst[1]); + } + } + } +} + +/* Used in do_tests, indexed by flags->nb_args + Elements correspond to enum test_flags::num args +*/ +static test_loop_t altivec_mov_loops[] = { + &test_move_special, + NULL +}; + +static test_loop_t altivec_dint_loops[] = { + &test_av_dint_two_args, + NULL +}; + +static test_table_t all_tests[] = { + { + tests_move_ops_spe, + "PPC VSR special move insns", + PPC_ALTIVEC | PPC_MOV | PPC_ONE_ARG, + }, + { + tests_aa_dbl_ops_two, + "PC altivec double word integer insns with two args", + PPC_ALTIVEC | PPC_ARITH | PPC_TWO_ARGS, + }, + { NULL, NULL, 0x00000000, }, +}; + +static void do_tests ( insn_sel_flags_t seln_flags, + char *filter) +{ + test_loop_t *loop; + test_t *tests; + int nb_args, type, family; + int i, j, n; + int exact; + + exact = check_filter(filter); + n = 0; + for (i=0; all_tests[i].name != NULL; i++) { + nb_args = all_tests[i].flags & PPC_NB_ARGS; + + /* Check number of arguments */ + if ((nb_args == 1 && !seln_flags.one_arg) || + (nb_args == 2 && !seln_flags.two_args) || + (nb_args == 3 && !seln_flags.three_args)){ + continue; + } + /* Check instruction type */ + type = all_tests[i].flags & PPC_TYPE; + if ((type == PPC_ARITH && !seln_flags.arith) || + (type == PPC_LOGICAL && !seln_flags.logical) || + (type == PPC_COMPARE && !seln_flags.compare) || + (type == PPC_LDST && !seln_flags.ldst) || + (type == PPC_MOV && !seln_flags.ldst) || + (type == PPC_POPCNT && !seln_flags.arith)) { + continue; + } + + /* Check instruction family */ + family = all_tests[i].flags & PPC_FAMILY; + if ((family == PPC_INTEGER && !seln_flags.integer) || + (family == PPC_FLOAT && !seln_flags.floats) || + (family == PPC_ALTIVEC && !seln_flags.altivec) || + (family == PPC_FALTIVEC && !seln_flags.faltivec)) { + continue; + } + /* Check flags update */ + if (((all_tests[i].flags & PPC_CR) && seln_flags.cr == 0) || + (!(all_tests[i].flags & PPC_CR) && seln_flags.cr == 1)) + continue; + + /* All passed, do the tests */ + tests = all_tests[i].tests; + + loop = NULL; + + /* Select the test loop */ + switch (family) { + case PPC_INTEGER: + printf("Currently there are no integer tests enabled in this testsuite.\n"); + break; + + case PPC_FLOAT: + printf("Currently there are no float tests enabled in this testsuite.\n"); + break; + + case PPC_ALTIVEC: + switch (type) { + case PPC_MOV: + loop = &altivec_mov_loops[0]; + break; + case PPC_ARITH: + loop = &altivec_dint_loops[0]; + break; + default: + printf("No altivec test defined for type %x\n", type); + } + break; + + case PPC_FALTIVEC: + printf("Currently there are no floating altivec tests in this testsuite.\n"); + break; + + default: + printf("ERROR: unknown insn family %08x\n", family); + continue; + } + if (1 || verbose > 0) + for (j=0; tests[j].name != NULL; j++) { + if (check_name(tests[j].name, filter, exact)) { + if (verbose > 1) + printf("Test instruction %s\n", tests[j].name); + if (loop != NULL) + (*loop)(tests[j].name, tests[j].func, all_tests[i].flags); + printf("\n"); + n++; + } + } + if (verbose) printf("\n"); + } + printf("All done. Tested %d different instructions\n", n); +} + + +static void usage (void) +{ + fprintf(stderr, + "Usage: jm-insns [OPTION]\n" + "\t-i: test integer instructions (default)\n" + "\t-f: test floating point instructions\n" + "\t-a: test altivec instructions\n" + "\t-A: test all (int, fp, altivec) instructions\n" + "\t-v: be verbose\n" + "\t-h: display this help and exit\n" + ); +} + +#endif + +int main (int argc, char **argv) +{ +#ifdef HAS_ISA_2_07 + /* Simple usage: + ./jm-insns -i => int insns + ./jm-insns -f => fp insns + ./jm-insns -a => av insns + ./jm-insns -A => int, fp and avinsns + */ + char *filter = NULL; + insn_sel_flags_t flags; + int c; + + // Args + flags.one_arg = 1; + flags.two_args = 1; + flags.three_args = 1; + // Type + flags.arith = 1; + flags.logical = 1; + flags.compare = 1; + flags.ldst = 1; + // Family + flags.integer = 0; + flags.floats = 0; + flags.altivec = 0; + flags.faltivec = 0; + // Flags + flags.cr = 2; + + while ((c = getopt(argc, argv, "ifahvA")) != -1) { + switch (c) { + case 'i': + flags.integer = 1; + break; + case 'f': + flags.floats = 1; + break; + case 'a': + flags.altivec = 1; + flags.faltivec = 1; + break; + case 'A': + flags.integer = 1; + flags.floats = 1; + flags.altivec = 1; + flags.faltivec = 1; + break; + case 'h': + usage(); + return 0; + case 'v': + verbose++; + break; + default: + usage(); + fprintf(stderr, "Unknown argument: '%c'\n", c); + return 1; + } + } + + arg_list_size = 0; + + build_vdargs_table(); + if (verbose > 1) { + printf("\nInstruction Selection:\n"); + printf(" n_args: \n"); + printf(" one_arg = %d\n", flags.one_arg); + printf(" two_args = %d\n", flags.two_args); + printf(" three_args = %d\n", flags.three_args); + printf(" type: \n"); + printf(" arith = %d\n", flags.arith); + printf(" logical = %d\n", flags.logical); + printf(" compare = %d\n", flags.compare); + printf(" ldst = %d\n", flags.ldst); + printf(" family: \n"); + printf(" integer = %d\n", flags.integer); + printf(" floats = %d\n", flags.floats); + printf(" altivec = %d\n", flags.altivec); + printf(" faltivec = %d\n", flags.faltivec); + printf(" cr update: \n"); + printf(" cr = %d\n", flags.cr); + printf("\n"); + } + + do_tests( flags, filter ); +#else + printf("NO ISA 2.07 SUPPORT\n"); +#endif + return 0; +} diff --git a/none/tests/ppc64/test_isa_2_07_part2.c b/none/tests/ppc64/test_isa_2_07_part2.c new file mode 100644 index 0000000..92e190c --- /dev/null +++ b/none/tests/ppc64/test_isa_2_07_part2.c @@ -0,0 +1,526 @@ +/* Copyright (C) 2013 IBM + + Authors: Carl Love + Maynard Johnson + + 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. + + The GNU General Public License is contained in the file COPYING. + + This program is based heavily on the test_isa_2_06_part*.c source files. + */ + +#include + +#ifdef HAS_ISA_2_07 + +#include +#include +#include +#include +#include +#include + +#ifndef __powerpc64__ +typedef uint32_t HWord_t; +#else +typedef uint64_t HWord_t; +#endif /* __powerpc64__ */ + +static int errors; +register HWord_t r14 __asm__ ("r14"); +register HWord_t r15 __asm__ ("r15"); +register HWord_t r16 __asm__ ("r16"); +register HWord_t r17 __asm__ ("r17"); +register double f14 __asm__ ("fr14"); +register double f15 __asm__ ("fr15"); +register double f16 __asm__ ("fr16"); +register double f17 __asm__ ("fr17"); + +static volatile unsigned int cond_reg; + +#define True 1 +#define False 0 + +#define ALLCR "cr0","cr1","cr2","cr3","cr4","cr5","cr6","cr7" + +#define SET_CR(_arg) \ + __asm__ __volatile__ ("mtcr %0" : : "b"(_arg) : ALLCR ); + +#define SET_XER(_arg) \ + __asm__ __volatile__ ("mtxer %0" : : "b"(_arg) : "xer" ); + +#define GET_CR(_lval) \ + __asm__ __volatile__ ("mfcr %0" : "=b"(_lval) ) + +#define GET_XER(_lval) \ + __asm__ __volatile__ ("mfxer %0" : "=b"(_lval) ) + +#define GET_CR_XER(_lval_cr,_lval_xer) \ + do { GET_CR(_lval_cr); GET_XER(_lval_xer); } while (0) + +#define SET_CR_ZERO \ + SET_CR(0) + +#define SET_XER_ZERO \ + SET_XER(0) + +#define SET_CR_XER_ZERO \ + do { SET_CR_ZERO; SET_XER_ZERO; } while (0) + +#define SET_FPSCR_ZERO \ + do { double _d = 0.0; \ + __asm__ __volatile__ ("mtfsf 0xFF, %0" : : "f"(_d) ); \ + } while (0) + + +typedef void (*test_func_t)(void); +typedef struct vsx_logic_test logic_test_t; +typedef struct ldst_test ldst_test_t; +typedef struct xs_conv_test xs_conv_test_t; +typedef struct vx_fp_test vx_fp_test_t; +typedef struct vx_fp_test2 vx_fp_test2_t; +typedef struct test_table test_table_t; + +typedef unsigned char Bool; + + +/* These functions below that construct a table of floating point + * values were lifted from none/tests/ppc32/jm-insns.c. + */ + +#if defined (DEBUG_ARGS_BUILD) +#define AB_DPRINTF(fmt, args...) do { fprintf(stderr, fmt , ##args); } while (0) +#else +#define AB_DPRINTF(fmt, args...) do { } while (0) +#endif + +static inline void register_farg (void *farg, + int s, uint16_t _exp, uint64_t mant) +{ + uint64_t tmp; + + tmp = ((uint64_t)s << 63) | ((uint64_t)_exp << 52) | mant; + *(uint64_t *)farg = tmp; + AB_DPRINTF("%d %03x %013llx => %016llx %0e\n", + s, _exp, mant, *(uint64_t *)farg, *(double *)farg); +} + + +typedef struct fp_test_args { + int fra_idx; + int frb_idx; + int cr_flags; + unsigned long long dp_bin_result; +} fp_test_args_t; + +static int nb_special_fargs; +static double * spec_fargs; +static float * spec_sp_fargs; + +static void build_special_fargs_table(void) +{ + /* The special floating point values created below are for + * use in the ftdiv tests for setting the fe_flag and fg_flag, + * but they can also be used for other tests (e.g., xscmpudp). + * + * Note that fl_flag is 'always '1' on ppc64 Linux. + * + Entry Sign Exp fraction Special value + 0 0 3fd 0x8000000000000ULL Positive finite number + 1 0 404 0xf000000000000ULL ... + 2 0 001 0x8000000b77501ULL ... + 3 0 7fe 0x800000000051bULL ... + 4 0 012 0x3214569900000ULL ... + 5 0 000 0x0000000000000ULL +0.0 (+zero) + 6 1 000 0x0000000000000ULL -0.0 (-zero) + 7 0 7ff 0x0000000000000ULL +infinity + 8 1 7ff 0x0000000000000ULL -infinity + 9 0 7ff 0x7FFFFFFFFFFFFULL +QNaN + 10 1 7ff 0x7FFFFFFFFFFFFULL -QNaN + 11 0 7ff 0x8000000000000ULL +SNaN + 12 1 7ff 0x8000000000000ULL -SNaN + 13 1 000 0x8340000078000ULL Denormalized val (zero exp and non-zero fraction) + 14 1 40d 0x0650f5a07b353ULL Negative finite number + */ + + uint64_t mant; + uint16_t _exp; + int s; + int j, i = 0; + + if (spec_fargs) + return; + + spec_fargs = malloc( 20 * sizeof(double) ); + spec_sp_fargs = malloc( 20 * sizeof(float) ); + + // #0 + s = 0; + _exp = 0x3fd; + mant = 0x8000000000000ULL; + register_farg(&spec_fargs[i++], s, _exp, mant); + + // #1 + s = 0; + _exp = 0x404; + mant = 0xf000000000000ULL; + register_farg(&spec_fargs[i++], s, _exp, mant); + + // #2 + s = 0; + _exp = 0x001; + mant = 0x8000000b77501ULL; + register_farg(&spec_fargs[i++], s, _exp, mant); + + // #3 + s = 0; + _exp = 0x7fe; + mant = 0x800000000051bULL; + register_farg(&spec_fargs[i++], s, _exp, mant); + + // #4 + s = 0; + _exp = 0x012; + mant = 0x3214569900000ULL; + register_farg(&spec_fargs[i++], s, _exp, mant); + + /* Special values */ + /* +0.0 : 0 0x000 0x0000000000000 */ + // #5 + s = 0; + _exp = 0x000; + mant = 0x0000000000000ULL; + register_farg(&spec_fargs[i++], s, _exp, mant); + + /* -0.0 : 1 0x000 0x0000000000000 */ + // #6 + s = 1; + _exp = 0x000; + mant = 0x0000000000000ULL; + register_farg(&spec_fargs[i++], s, _exp, mant); + + /* +infinity : 0 0x7FF 0x0000000000000 */ + // #7 + s = 0; + _exp = 0x7FF; + mant = 0x0000000000000ULL; + register_farg(&spec_fargs[i++], s, _exp, mant); + + /* -infinity : 1 0x7FF 0x0000000000000 */ + // #8 + s = 1; + _exp = 0x7FF; + mant = 0x0000000000000ULL; + register_farg(&spec_fargs[i++], s, _exp, mant); + + /* +QNaN : 0 0x7FF 0x7FFFFFFFFFFFF */ + // #9 + s = 0; + _exp = 0x7FF; + mant = 0x7FFFFFFFFFFFFULL; + register_farg(&spec_fargs[i++], s, _exp, mant); + + /* -QNaN : 1 0x7FF 0x7FFFFFFFFFFFF */ + // #10 + s = 1; + _exp = 0x7FF; + mant = 0x7FFFFFFFFFFFFULL; + register_farg(&spec_fargs[i++], s, _exp, mant); + + /* +SNaN : 0 0x7FF 0x8000000000000 */ + // #11 + s = 0; + _exp = 0x7FF; + mant = 0x8000000000000ULL; + register_farg(&spec_fargs[i++], s, _exp, mant); + + /* -SNaN : 1 0x7FF 0x8000000000000 */ + // #12 + s = 1; + _exp = 0x7FF; + mant = 0x8000000000000ULL; + register_farg(&spec_fargs[i++], s, _exp, mant); + + /* denormalized value */ + // #13 + s = 1; + _exp = 0x000; + mant = 0x8340000078000ULL; + register_farg(&spec_fargs[i++], s, _exp, mant); + + /* Negative finite number */ + // #14 + s = 1; + _exp = 0x40d; + mant = 0x0650f5a07b353ULL; + register_farg(&spec_fargs[i++], s, _exp, mant); + + /* A few positive finite numbers ... */ + // #15 + s = 0; + _exp = 0x412; + mant = 0x32585a9900000ULL; + register_farg(&spec_fargs[i++], s, _exp, mant); + + // #16 + s = 0; + _exp = 0x413; + mant = 0x82511a2000000ULL; + register_farg(&spec_fargs[i++], s, _exp, mant); + + // #17 + s = 0; + _exp = 0x403; + mant = 0x12ef5a9300000ULL; + register_farg(&spec_fargs[i++], s, _exp, mant); + + // #18 + s = 0; + _exp = 0x405; + mant = 0x14bf5d2300000ULL; + register_farg(&spec_fargs[i++], s, _exp, mant); + + // #19 + s = 0; + _exp = 0x409; + mant = 0x76bf982440000ULL; + register_farg(&spec_fargs[i++], s, _exp, mant); + + + nb_special_fargs = i; + for (j = 0; j < i; j++) { + spec_sp_fargs[j] = spec_fargs[j]; + } +} + +struct test_table +{ + test_func_t test_category; + char * name; +}; + + +typedef enum { + SINGLE_TEST, + DOUBLE_TEST, + DOUBLE_TEST_SINGLE_RES +} precision_type_t; + +typedef enum { + VX_FP_SMAS, // multiply add single precision result + VX_FP_SMSS, // multiply sub single precision result + VX_FP_SNMAS, // negative multiply add single precision result + VX_FP_SNMSS, // negative multiply sub single precision result + VX_FP_OTHER, + VX_CONV_WORD, + VX_ESTIMATE, + VX_CONV_TO_SINGLE, + VX_CONV_TO_DOUBLE, + VX_SCALAR_CONV_TO_WORD, + VX_DEFAULT +} vx_fp_test_type; + + +struct vx_fp_test2 +{ + test_func_t test_func; + const char *name; + fp_test_args_t * targs; + int num_tests; + precision_type_t precision; + vx_fp_test_type test_type; + const char * op; +}; + +static vector unsigned int vec_out, vec_inB; + +static void test_xscvdpspn(void) +{ + __asm__ __volatile__ ("xscvdpspn %x0, %x1" : "=wa" (vec_out): "wa" (vec_inB)); +} + +static void test_xscvspdpn(void) +{ + __asm__ __volatile__ ("xscvspdpn %x0, %x1" : "=wa" (vec_out): "wa" (vec_inB)); +} +static vx_fp_test2_t +vsx_one_fp_arg_tests[] = { + { &test_xscvdpspn, "xscvdpspn", NULL, 20, DOUBLE_TEST, VX_CONV_TO_SINGLE, "conv"}, + { &test_xscvspdpn, "xscvspdpn", NULL, 20, SINGLE_TEST, VX_CONV_TO_DOUBLE, "conv"}, + { NULL, NULL, NULL, 0, 0, 0, NULL} +}; + + +static void test_vsx_one_fp_arg(void) +{ + test_func_t func; + int k; + k = 0; + build_special_fargs_table(); + + while ((func = vsx_one_fp_arg_tests[k].test_func)) { + int idx, i; + vx_fp_test2_t test_group = vsx_one_fp_arg_tests[k]; + /* size of source operands */ + Bool dp = ((test_group.precision == DOUBLE_TEST) || + (test_group.precision == DOUBLE_TEST_SINGLE_RES)) ? True : False; + /* size of result */ + Bool is_sqrt = (strstr(test_group.name, "sqrt")) ? True : False; + Bool is_scalar = (strstr(test_group.name, "xs")) ? True : False; + Bool sparse_sp = False; + int stride = dp ? 2 : 4; + int loops = is_scalar ? 1 : stride; + stride = is_scalar ? 1: stride; + + /* For conversions of single to double, the 128-bit input register is sparsely populated: + * |___ SP___|_Unused_|___SP___|__Unused__| // for vector op + * or + * |___ SP___|_Unused_|_Unused_|__Unused__| // for scalar op + * + * For the vector op case, we need to adjust stride from '4' to '2', since + * we'll only be loading two values per loop into the input register. + */ + if (!dp && !is_scalar && test_group.test_type == VX_CONV_TO_DOUBLE) { + sparse_sp = True; + stride = 2; + } + + for (i = 0; i < test_group.num_tests; i+=stride) { + unsigned int * pv; + void * inB; + + pv = (unsigned int *)&vec_out; + // clear vec_out + for (idx = 0; idx < 4; idx++, pv++) + *pv = 0; + + if (dp) { + int j; + unsigned long long * frB_dp, *dst_dp; + for (j = 0; j < loops; j++) { + inB = (void *)&spec_fargs[i + j]; + // copy double precision FP into vector element i + memcpy(((void *)&vec_inB) + (j * 8), inB, 8); + } + // execute test insn + (*func)(); + dst_dp = (unsigned long long *) &vec_out; + printf("#%d: %s ", i/stride, test_group.name); + for (j = 0; j < loops; j++) { + if (j) + printf("; "); + frB_dp = (unsigned long long *)&spec_fargs[i + j]; + printf("%s(%016llx)", test_group.op, *frB_dp); + vx_fp_test_type type = test_group.test_type; + switch (type) { + case VX_SCALAR_CONV_TO_WORD: + printf(" = %016llx", dst_dp[j] & 0x00000000ffffffffULL); + break; + case VX_CONV_TO_SINGLE: + printf(" = %016llx", dst_dp[j] & 0xffffffff00000000ULL); + break; + default: // For VX_CONV_TO_DOUBLE and non-convert instructions . . . + printf(" = %016llx", dst_dp[j]); + } + } + printf("\n"); + } else { + int j, skip_slot; + unsigned int * frB_sp, * dst_sp = NULL; + unsigned long long * dst_dp = NULL; + if (sparse_sp) { + skip_slot = 1; + loops = 2; + } else { + skip_slot = 0; + } + for (j = 0; j < loops; j++) { + inB = (void *)&spec_sp_fargs[i + j]; + // copy single precision FP into vector element i + + if (skip_slot && j > 0) + memcpy(((void *)&vec_inB) + ((j + j) * 4), inB, 4); + else + memcpy(((void *)&vec_inB) + (j * 4), inB, 4); + } + // execute test insn + (*func)(); + if (test_group.test_type == VX_CONV_TO_DOUBLE) + dst_dp = (unsigned long long *) &vec_out; + else + dst_sp = (unsigned int *) &vec_out; + // print result + printf("#%d: %s ", i/stride, test_group.name); + for (j = 0; j < loops; j++) { + if (j) + printf("; "); + frB_sp = (unsigned int *)&spec_sp_fargs[i + j]; + printf("%s(%08x)", test_group.op, *frB_sp); + if (test_group.test_type == VX_CONV_TO_DOUBLE) + printf(" = %016llx", dst_dp[j]); + else + /* Special case: Current VEX implementation for fsqrts (single precision) + * uses the same implementation as that used for double precision fsqrt. + * However, I've found that for xvsqrtsp, the result from that implementation + * may be off by the two LSBs. Generally, even this small inaccuracy can cause the + * output to appear very different if you end up with a carry. But for the given + * inputs in this testcase, we can simply mask out these bits. + */ + printf(" = %08x", is_sqrt ? (dst_sp[j] & 0xfffffffc) : dst_sp[j]); + } + printf("\n"); + } + } + k++; + printf( "\n" ); + } +} + +//---------------------------------------------------------- + +static test_table_t all_tests[] = { + { &test_vsx_one_fp_arg, + "Test VSX vector and scalar single argument instructions"} , + { NULL, NULL } +}; + +#endif + +int main(int argc, char *argv[]) +{ + +#ifdef HAS_ISA_2_07 + test_table_t aTest; + test_func_t func; + int i = 0; + + while ((func = all_tests[i].test_category)) { + aTest = all_tests[i]; + printf( "%s\n", aTest.name ); + (*func)(); + i++; + } + if (errors) + printf("Testcase FAILED with %d errors \n", errors); + else + printf("Testcase PASSED\n"); + +#else + printf("NO ISA 2.07 SUPPORT\n"); +#endif + return 0; +} diff --git a/none/tests/ppc64/test_isa_2_07_part2.stderr.exp b/none/tests/ppc64/test_isa_2_07_part2.stderr.exp new file mode 100644 index 0000000..139597f --- /dev/null +++ b/none/tests/ppc64/test_isa_2_07_part2.stderr.exp @@ -0,0 +1,2 @@ + + diff --git a/none/tests/ppc64/test_isa_2_07_part2.stdout.exp b/none/tests/ppc64/test_isa_2_07_part2.stdout.exp new file mode 100644 index 0000000..c65c574 --- /dev/null +++ b/none/tests/ppc64/test_isa_2_07_part2.stdout.exp @@ -0,0 +1,44 @@ +Test VSX vector and scalar single argument instructions +#0: xscvdpspn conv(3fd8000000000000) = 3ec0000000000000 +#1: xscvdpspn conv(404f000000000000) = 4278000000000000 +#2: xscvdpspn conv(0018000000b77501) = 0000000000000000 +#3: xscvdpspn conv(7fe800000000051b) = 7f40000000000000 +#4: xscvdpspn conv(0123214569900000) = 0000000000000000 +#5: xscvdpspn conv(0000000000000000) = 0000000000000000 +#6: xscvdpspn conv(8000000000000000) = 8000000000000000 +#7: xscvdpspn conv(7ff0000000000000) = 7f80000000000000 +#8: xscvdpspn conv(fff0000000000000) = ff80000000000000 +#9: xscvdpspn conv(7ff7ffffffffffff) = 7fbfffff00000000 +#10: xscvdpspn conv(fff7ffffffffffff) = ffbfffff00000000 +#11: xscvdpspn conv(7ff8000000000000) = 7fc0000000000000 +#12: xscvdpspn conv(fff8000000000000) = ffc0000000000000 +#13: xscvdpspn conv(8008340000078000) = 8000000000000000 +#14: xscvdpspn conv(c0d0650f5a07b353) = c683287a00000000 +#15: xscvdpspn conv(41232585a9900000) = 49192c2d00000000 +#16: xscvdpspn conv(41382511a2000000) = 49c1288d00000000 +#17: xscvdpspn conv(40312ef5a9300000) = 418977ad00000000 +#18: xscvdpspn conv(40514bf5d2300000) = 428a5fae00000000 +#19: xscvdpspn conv(40976bf982440000) = 44bb5fcc00000000 + +#0: xscvspdpn conv(3ec00000) = 3fd8000000000000 +#1: xscvspdpn conv(42780000) = 404f000000000000 +#2: xscvspdpn conv(00000000) = 0000000000000000 +#3: xscvspdpn conv(7f800000) = 7ff0000000000000 +#4: xscvspdpn conv(00000000) = 0000000000000000 +#5: xscvspdpn conv(00000000) = 0000000000000000 +#6: xscvspdpn conv(80000000) = 8000000000000000 +#7: xscvspdpn conv(7f800000) = 7ff0000000000000 +#8: xscvspdpn conv(ff800000) = fff0000000000000 +#9: xscvspdpn conv(7fffffff) = 7fffffffe0000000 +#10: xscvspdpn conv(ffffffff) = ffffffffe0000000 +#11: xscvspdpn conv(7fc00000) = 7ff8000000000000 +#12: xscvspdpn conv(ffc00000) = fff8000000000000 +#13: xscvspdpn conv(80000000) = 8000000000000000 +#14: xscvspdpn conv(c683287b) = c0d0650f60000000 +#15: xscvspdpn conv(49192c2d) = 41232585a0000000 +#16: xscvspdpn conv(49c1288d) = 41382511a0000000 +#17: xscvspdpn conv(418977ad) = 40312ef5a0000000 +#18: xscvspdpn conv(428a5faf) = 40514bf5e0000000 +#19: xscvspdpn conv(44bb5fcc) = 40976bf980000000 + +Testcase PASSED diff --git a/none/tests/ppc64/test_isa_2_07_part2.vgtest b/none/tests/ppc64/test_isa_2_07_part2.vgtest new file mode 100644 index 0000000..a4649be --- /dev/null +++ b/none/tests/ppc64/test_isa_2_07_part2.vgtest @@ -0,0 +1,2 @@ +prereq: ../../../tests/check_isa-2_07_cap +prog: test_isa_2_07_part2 diff --git a/tests/check_isa-2_07_cap b/tests/check_isa-2_07_cap new file mode 100755 index 0000000..ee777c1 --- /dev/null +++ b/tests/check_isa-2_07_cap @@ -0,0 +1,12 @@ +#!/bin/sh + +# We use this script to check whether or not the processor supports +# Power ISA 2.07. +DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" +LD_SHOW_AUXV=1 $DIR/true | grep arch_2_07 > /dev/null 2>&1 + +if [ "$?" -ne "0" ]; then + exit 1 +else + exit 0 +fi