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 runtime and testsuite 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, VEX commit 2740

git-svn-id: svn://svn.valgrind.org/valgrind/trunk@13494 a5019735-40e9-0310-863c-91ae7b9d1cf9
diff --git a/configure.in b/configure.in
index 5cf28a1..c51f465 100644
--- a/configure.in
+++ b/configure.in
@@ -1296,6 +1296,21 @@
 
 AM_CONDITIONAL(BUILD_DFP_TESTS, test x$ac_gcc_have_dfp_type = xyes)
 
+# 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)
 
 # Check for pthread_create@GLIBC2.0
 AC_MSG_CHECKING([for pthread_create@GLIBC2.0()])
diff --git a/coregrind/m_machine.c b/coregrind/m_machine.c
index ab5bc31..353c05b 100644
--- a/coregrind/m_machine.c
+++ b/coregrind/m_machine.c
@@ -887,6 +887,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
@@ -981,6 +982,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);
@@ -991,9 +1000,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;
@@ -1014,6 +1024,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;
 
      VG_(machine_get_cache_info)(&vai);
 
@@ -1030,6 +1041,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
@@ -1116,6 +1128,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);
@@ -1123,9 +1143,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;
@@ -1140,6 +1161,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;
 
      VG_(machine_get_cache_info)(&vai);
 
diff --git a/memcheck/mc_translate.c b/memcheck/mc_translate.c
index 079ca2a..33dc1ce 100644
--- a/memcheck/mc_translate.c
+++ b/memcheck/mc_translate.c
@@ -3357,6 +3357,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 --git a/memcheck/tests/vbit-test/irops.c b/memcheck/tests/vbit-test/irops.c
index c0ba5ee..49bb9c4 100644
--- a/memcheck/tests/vbit-test/irops.c
+++ b/memcheck/tests/vbit-test/irops.c
@@ -806,6 +806,7 @@
   { DEFOP(Iop_QNarrowBin32Uto16Ux8, UNDEF_UNKNOWN), },
   { DEFOP(Iop_NarrowBin16to8x16, UNDEF_UNKNOWN), },
   { DEFOP(Iop_NarrowBin32to16x8, UNDEF_UNKNOWN), },
+  { DEFOP(Iop_NarrowBin64to32x4, UNDEF_UNKNOWN), },
   { DEFOP(Iop_NarrowUn16to8x8, UNDEF_UNKNOWN), },
   { DEFOP(Iop_NarrowUn32to16x4, UNDEF_UNKNOWN), },
   { DEFOP(Iop_NarrowUn64to32x2, UNDEF_UNKNOWN), },
diff --git a/none/tests/ppc32/Makefile.am b/none/tests/ppc32/Makefile.am
index 976d9f4..e7abf3f 100644
--- a/none/tests/ppc32/Makefile.am
+++ b/none/tests/ppc32/Makefile.am
@@ -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_M64@ $(BUILD_FLAGS_ISA_2_07)
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/Makefile.am b/none/tests/ppc64/Makefile.am
index 3213e53..d39380e 100644
--- a/none/tests/ppc64/Makefile.am
+++ b/none/tests/ppc64/Makefile.am
@@ -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 --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 100644
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 <carll@us.ibm.com>
+ *            Maynard Johnson <maynardj@us.ibm.com>
+ *
+ *   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 <stdio.h>
+
+#ifdef HAS_ISA_2_07
+
+#include "config.h"
+#include <altivec.h>
+#include <stdint.h>
+
+#include <assert.h>
+#include <ctype.h>     // isspace
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>    // 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  <carll@us.ibm.com>
+          Maynard Johnson <maynardj@us.ibm.com>
+
+ 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 <stdio.h>
+
+#ifdef HAS_ISA_2_07
+
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+#include <malloc.h>
+#include <altivec.h>
+#include <math.h>
+
+#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_06_cap b/tests/check_isa-2_06_cap
index 2b91cb0..c5fc05a 100755
--- a/tests/check_isa-2_06_cap
+++ b/tests/check_isa-2_06_cap
@@ -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 --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