tests/arch_test is currently being used for two purposes:
- by vg_regtest for determining if a directory name matches an architecture;
- by various .vgtest files for detecting x86/AMD64 features.

This commit splits it in two for the two different purposes, which makes
things clearer.

Specific changes

- Moved the x86/AMD64 feature detection stuff out of arch_test.c, and
  into the new x86_amd64_feature.c.  Updated the relevant .vgtest files for
  the change.

- In vg_regtest, now a prereq command must return 0 (prereq satisfied) or 1
  (prereq not satisfied).  Anything else makes vg_regtest abort.  This
  makes obvious any problems with prereq tests rather than just making the
  tests skip innocuously.  (We previously had exactly such a problem on the
  DARWIN branch;  the x86 feature detection tests caused segfaults so the
  tests were incorrectly skipped.  This change will catch any similar future
  problem.)

- Changed os_test from a script to a C program, matching cpu_test.

- Removed some unintentional darwin stuff from platform_test.


git-svn-id: svn://svn.valgrind.org/valgrind/trunk@9316 a5019735-40e9-0310-863c-91ae7b9d1cf9
diff --git a/configure.in b/configure.in
index a3dcd83..c2021dc 100644
--- a/configure.in
+++ b/configure.in
@@ -1709,7 +1709,6 @@
    docs/xml/Makefile
    tests/Makefile 
    tests/vg_regtest 
-   tests/os_test 
    perf/Makefile 
    perf/vg_perf
    include/Makefile 
diff --git a/memcheck/tests/x86/fxsave.vgtest b/memcheck/tests/x86/fxsave.vgtest
index 93a87a9..e7eb36d 100644
--- a/memcheck/tests/x86/fxsave.vgtest
+++ b/memcheck/tests/x86/fxsave.vgtest
@@ -1,4 +1,4 @@
 prog: fxsave
-prereq: ../../../tests/arch_test x86-sse
+prereq: ../../../tests/x86_amd64_features x86-sse
 vgopts: -q
 args: x
diff --git a/memcheck/tests/x86/sse1_memory.vgtest b/memcheck/tests/x86/sse1_memory.vgtest
index cf6cd55..439e180 100644
--- a/memcheck/tests/x86/sse1_memory.vgtest
+++ b/memcheck/tests/x86/sse1_memory.vgtest
@@ -1,4 +1,4 @@
 prog: sse_memory
 vgopts: -q
 args: sse1
-prereq: ../../../tests/arch_test x86-sse
+prereq: ../../../tests/x86_amd64_features x86-sse
diff --git a/memcheck/tests/x86/sse2_memory.vgtest b/memcheck/tests/x86/sse2_memory.vgtest
index 1fe8856..96452ae 100644
--- a/memcheck/tests/x86/sse2_memory.vgtest
+++ b/memcheck/tests/x86/sse2_memory.vgtest
@@ -1,4 +1,4 @@
 prog: sse_memory
 vgopts: -q
 args: sse2
-prereq: ../../../tests/arch_test x86-sse2
+prereq: ../../../tests/x86_amd64_features x86-sse2
diff --git a/memcheck/tests/x86/xor-undef-x86.vgtest b/memcheck/tests/x86/xor-undef-x86.vgtest
index 495a57c..4727280 100644
--- a/memcheck/tests/x86/xor-undef-x86.vgtest
+++ b/memcheck/tests/x86/xor-undef-x86.vgtest
@@ -1,2 +1,2 @@
 prog: xor-undef-x86
-prereq: ../../../tests/arch_test x86-sse
+prereq: ../../../tests/x86_amd64_features x86-sse
diff --git a/none/tests/amd64/insn_sse3.vgtest b/none/tests/amd64/insn_sse3.vgtest
index ccf6cff..d4141b1 100644
--- a/none/tests/amd64/insn_sse3.vgtest
+++ b/none/tests/amd64/insn_sse3.vgtest
@@ -1,3 +1,3 @@
 prog: ../../../none/tests/amd64/insn_sse3
-prereq: ../../../tests/arch_test amd64-sse3
+prereq: ../../../tests/x86_amd64_features amd64-sse3
 vgopts: -q
diff --git a/none/tests/amd64/insn_ssse3.vgtest b/none/tests/amd64/insn_ssse3.vgtest
index d08dc3d..17d51e8 100644
--- a/none/tests/amd64/insn_ssse3.vgtest
+++ b/none/tests/amd64/insn_ssse3.vgtest
@@ -1,3 +1,3 @@
 prog: ../../../none/tests/amd64/insn_ssse3
-prereq: ../../../tests/arch_test amd64-ssse3
+prereq: ../../../tests/x86_amd64_features amd64-ssse3
 vgopts: -q
diff --git a/none/tests/amd64/ssse3_misaligned.vgtest b/none/tests/amd64/ssse3_misaligned.vgtest
index 76255d9..ae0a6f8 100644
--- a/none/tests/amd64/ssse3_misaligned.vgtest
+++ b/none/tests/amd64/ssse3_misaligned.vgtest
@@ -1,3 +1,3 @@
 prog: ssse3_misaligned
-prereq: ../../../tests/arch_test amd64-ssse3
+prereq: ../../../tests/x86_amd64_features amd64-ssse3
 vgopts: -q
diff --git a/none/tests/x86/bug137714-x86.vgtest b/none/tests/x86/bug137714-x86.vgtest
index ab1560e..3634578 100644
--- a/none/tests/x86/bug137714-x86.vgtest
+++ b/none/tests/x86/bug137714-x86.vgtest
@@ -1,3 +1,3 @@
 prog: bug137714-x86
-prereq: ../../../tests/arch_test x86-sse2
+prereq: ../../../tests/x86_amd64_features x86-sse2
 vgopts: -q
diff --git a/none/tests/x86/cse_fail.vgtest b/none/tests/x86/cse_fail.vgtest
index 6c0092c..b3505ff 100644
--- a/none/tests/x86/cse_fail.vgtest
+++ b/none/tests/x86/cse_fail.vgtest
@@ -1,3 +1,3 @@
 prog: cse_fail
-prereq: ../../../tests/arch_test x86-sse
+prereq: ../../../tests/x86_amd64_features x86-sse
 vgopts: -q
diff --git a/none/tests/x86/gen_insn_test.pl b/none/tests/x86/gen_insn_test.pl
index d97eee8..c75df1d 100644
--- a/none/tests/x86/gen_insn_test.pl
+++ b/none/tests/x86/gen_insn_test.pl
@@ -49,8 +49,8 @@
 
 our %RegNums = (
                 al => 0, ax => 0, eax => 0,
-                bl => 1, bx => 1, ebx => 1,
                 cl => 2, cx => 2, ecx => 2,
+                bl => 1, bx => 1, ebx => 1,
                 dl => 3, dx => 3, edx => 3,
                 ah => 4,
                 bh => 5,
@@ -62,15 +62,15 @@
 
 our %RegTypes = (
                  al => "r8", ah => "r8", ax => "r16", eax => "r32",
-                 bl => "r8", bh => "r8", bx => "r16", ebx => "r32",
                  cl => "r8", ch => "r8", cx => "r16", ecx => "r32",
+                 bl => "r8", bh => "r8", bx => "r16", ebx => "r32",
                  dl => "r8", dh => "r8", dx => "r16", edx => "r32"
                  );
 
 our @IntRegs = (
                 { r8 => "al", r16 => "ax", r32 => "eax" },
-                { r8 => "bl", r16 => "bx", r32 => "ebx" },
                 { r8 => "cl", r16 => "cx", r32 => "ecx" },
+                { r8 => "bl", r16 => "bx", r32 => "ebx" },
                 { r8 => "dl", r16 => "dx", r32 => "edx" },
                 { r8 => "ah" },
                 { r8 => "bh" },
diff --git a/none/tests/x86/insn_cmov.vgtest b/none/tests/x86/insn_cmov.vgtest
index 42b44b9..42dd140 100644
--- a/none/tests/x86/insn_cmov.vgtest
+++ b/none/tests/x86/insn_cmov.vgtest
@@ -1,3 +1,3 @@
 prog: ../../../none/tests/x86/insn_cmov
-prereq: ../../../tests/arch_test x86-cmov
+prereq: ../../../tests/x86_amd64_features x86-cmov
 vgopts: -q
diff --git a/none/tests/x86/insn_fpu.vgtest b/none/tests/x86/insn_fpu.vgtest
index 01e514a..f0b1e48 100644
--- a/none/tests/x86/insn_fpu.vgtest
+++ b/none/tests/x86/insn_fpu.vgtest
@@ -1,3 +1,3 @@
 prog: ../../../none/tests/x86/insn_fpu
-prereq: ../../../tests/arch_test x86-fpu
+prereq: ../../../tests/x86_amd64_features x86-fpu
 vgopts: -q
diff --git a/none/tests/x86/insn_mmx.vgtest b/none/tests/x86/insn_mmx.vgtest
index 88adf5b..05976ae 100644
--- a/none/tests/x86/insn_mmx.vgtest
+++ b/none/tests/x86/insn_mmx.vgtest
@@ -1,3 +1,3 @@
 prog: ../../../none/tests/x86/insn_mmx
-prereq: ../../../tests/arch_test x86-mmx
+prereq: ../../../tests/x86_amd64_features x86-mmx
 vgopts: -q
diff --git a/none/tests/x86/insn_mmxext.vgtest b/none/tests/x86/insn_mmxext.vgtest
index 2b42ff4..ad48b6e 100644
--- a/none/tests/x86/insn_mmxext.vgtest
+++ b/none/tests/x86/insn_mmxext.vgtest
@@ -1,3 +1,3 @@
 prog: ../../../none/tests/x86/insn_mmxext
-prereq: ../../../tests/arch_test x86-mmxext
+prereq: ../../../tests/x86_amd64_features x86-mmxext
 vgopts: -q
diff --git a/none/tests/x86/insn_sse.vgtest b/none/tests/x86/insn_sse.vgtest
index 24a7f06..8babe72 100644
--- a/none/tests/x86/insn_sse.vgtest
+++ b/none/tests/x86/insn_sse.vgtest
@@ -1,3 +1,3 @@
 prog: ../../../none/tests/x86/insn_sse
-prereq: ../../../tests/arch_test x86-sse
+prereq: ../../../tests/x86_amd64_features x86-sse
 vgopts: -q
diff --git a/none/tests/x86/insn_sse2.vgtest b/none/tests/x86/insn_sse2.vgtest
index a13a51d..6ae6a74 100644
--- a/none/tests/x86/insn_sse2.vgtest
+++ b/none/tests/x86/insn_sse2.vgtest
@@ -1,3 +1,3 @@
 prog: ../../../none/tests/x86/insn_sse2
-prereq: ../../../tests/arch_test x86-sse2
+prereq: ../../../tests/x86_amd64_features x86-sse2
 vgopts: -q
diff --git a/none/tests/x86/insn_sse3.vgtest b/none/tests/x86/insn_sse3.vgtest
index 6c67999..42a9f2a 100644
--- a/none/tests/x86/insn_sse3.vgtest
+++ b/none/tests/x86/insn_sse3.vgtest
@@ -1,3 +1,3 @@
 prog: ../../../none/tests/x86/insn_sse3
-prereq: ../../../tests/arch_test x86-sse3
+prereq: ../../../tests/x86_amd64_features x86-sse3
 vgopts: -q
diff --git a/none/tests/x86/insn_ssse3.vgtest b/none/tests/x86/insn_ssse3.vgtest
index c9b5a61..73ce799 100644
--- a/none/tests/x86/insn_ssse3.vgtest
+++ b/none/tests/x86/insn_ssse3.vgtest
@@ -1,3 +1,3 @@
 prog: ../../../none/tests/x86/insn_ssse3
-prereq: ../../../tests/arch_test x86-ssse3
+prereq: ../../../tests/x86_amd64_features x86-ssse3
 vgopts: -q
diff --git a/none/tests/x86/ssse3_misaligned.vgtest b/none/tests/x86/ssse3_misaligned.vgtest
index bd570b6..45db4f0 100644
--- a/none/tests/x86/ssse3_misaligned.vgtest
+++ b/none/tests/x86/ssse3_misaligned.vgtest
@@ -1,3 +1,3 @@
 prog: ssse3_misaligned
-prereq: ../../../tests/arch_test x86-ssse3
+prereq: ../../../tests/x86_amd64_features x86-ssse3
 vgopts: -q
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 70fefaf..f292f77 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -8,7 +8,6 @@
 	filter_numbers \
 	filter_stderr_basic \
 	filter_sink \
-	os_test \
 	platform_test \
 	vg_regtest
 
@@ -16,7 +15,9 @@
 
 check_PROGRAMS = \
 	arch_test \
-	true
+	os_test \
+	true \
+	x86_amd64_features
 
 AM_CFLAGS   += $(AM_FLAG_M3264_PRI)
 AM_CXXFLAGS += $(AM_FLAG_M3264_PRI)
diff --git a/tests/arch_test.c b/tests/arch_test.c
index feeb67e..f6206e3 100644
--- a/tests/arch_test.c
+++ b/tests/arch_test.c
@@ -1,18 +1,19 @@
+
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
-#include <assert.h>
 
-// This file determines which architectures that this Valgrind installation
-// supports, which depends on the machine's architecture.  It also depends
-// on the configuration options;  for example, if Valgrind is installed on
-// an AMD64 machine but has been configured with --enable-only32bit then
-// this program will not match "amd64".
+// This program determines which architectures that this Valgrind installation
+// supports, which depends on the what was chosen at configure-time.  For
+// example, if Valgrind is installed on an AMD64 machine but has been
+// configured with --enable-only32bit then this program will match "x86" but
+// not "amd64".
 //
 // We return:
-// - 0 if the machine matches the asked-for cpu
-// - 1 if it didn't match, but did match the name of another arch
-// - 2 otherwise
+// - 0 if the machine matches the asked-for arch
+// - 1 if it doesn't match but does match the name of another arch
+// - 2 if it doesn't match the name of any arch
+// - 3 if there was a usage error (it also prints an error message)
 
 // Nb: When updating this file for a new architecture, add the name to
 // 'all_archs' as well as adding go().
@@ -22,138 +23,44 @@
 typedef int    Bool;
 
 char* all_archs[] = {
+   "x86",
    "amd64",
    "ppc32",
    "ppc64",
-   "x86",
    NULL
 };
 
-//-----------------------------------------------------------------------------
-// ppc32-linux
-//---------------------------------------------------------------------------
-#if defined(VGP_ppc32_linux)
-static Bool go(char* cpu)
-{
-   if ( strcmp( cpu, "ppc32" ) == 0 )
-      return True;
-   return False;
-}
-#endif   // VGP_ppc32_linux
-
-//---------------------------------------------------------------------------
-// ppc64-linux
-//---------------------------------------------------------------------------
-#if defined(VGP_ppc64_linux)
-static Bool go(char* cpu)
-{
-   if ( strcmp( cpu, "ppc64" ) == 0 )
-      return True;
-   if ( strcmp( cpu, "ppc32" ) == 0 )
-      return True;
-   return False;
-}
-#endif   // VGP_ppc64_linux
-
-//---------------------------------------------------------------------------
-// ppc{32,64}-aix
-//---------------------------------------------------------------------------
-#if defined(VGP_ppc32_aix5) || defined(VGP_ppc64_aix5)
-static Bool go(char* cpu)
-{
-   if (sizeof(void*) == 8) {
-      /* cpu is in 64-bit mode */
-      if ( strcmp( cpu, "ppc64" ) == 0 )
-         return True;
-      if ( strcmp( cpu, "ppc32" ) == 0 )
-         return True;
-   } else {
-      if ( strcmp( cpu, "ppc32" ) == 0 )
-         return True;
-   }
-   return False;
-}
-#endif   // VGP_ppc32_aix5 || VGP_ppc64_aix5
-
-//---------------------------------------------------------------------------
-// {x86,amd64}-linux (part 1 of 2)
-//---------------------------------------------------------------------------
-#if defined(VGP_x86_linux) || defined(VGP_amd64_linux)
-static void cpuid ( unsigned int n,
-                    unsigned int* a, unsigned int* b,
-                    unsigned int* c, unsigned int* d )
-{
-   __asm__ __volatile__ (
-      "cpuid"
-      : "=a" (*a), "=b" (*b), "=c" (*c), "=d" (*d)      /* output */
-      : "0" (n)         /* input */
-   );
-}
-#endif   // VGP_x86_linux || VGP_amd64_linux
-
-//---------------------------------------------------------------------------
-// {x86,amd64}-linux (part 2 of 2)
-//---------------------------------------------------------------------------
-#if defined(VGP_x86_linux)  || defined(VGP_amd64_linux)
-static Bool go(char* cpu)
+static Bool go(char* arch)
 { 
-   unsigned int level = 0, cmask = 0, dmask = 0, a, b, c, d;
+#if defined(VGP_x86_linux)
+   if ( 0 == strcmp( arch, "x86"   ) ) return True;
 
-   if ( strcmp( cpu, "x86" ) == 0 ) {
-     return True;
-   } else if ( strcmp( cpu, "x86-fpu" ) == 0 ) {
-     level = 1;
-     dmask = 1 << 0;
-   } else if ( strcmp( cpu, "x86-cmov" ) == 0 ) {
-     level = 1;
-     dmask = 1 << 15;
-   } else if ( strcmp( cpu, "x86-mmx" ) == 0 ) {
-     level = 1;
-     dmask = 1 << 23;
-   } else if ( strcmp( cpu, "x86-mmxext" ) == 0 ) {
-     level = 0x80000001;
-     dmask = 1 << 22;
-   } else if ( strcmp( cpu, "x86-sse" ) == 0 ) {
-     level = 1;
-     dmask = 1 << 25;
-   } else if ( strcmp( cpu, "x86-sse2" ) == 0 ) {
-     level = 1;
-     dmask = 1 << 26;
-   } else if ( strcmp( cpu, "x86-sse3" ) == 0 ) {
-     level = 1;
-     cmask = 1 << 0;
-   } else if ( strcmp( cpu, "x86-ssse3" ) == 0 ) {
-     level = 1;
-     cmask = 1 << 9;
-#if defined(VGA_amd64)
-   } else if ( strcmp( cpu, "amd64" ) == 0 ) {
-     return True;
-   } else if ( strcmp( cpu, "amd64-sse3" ) == 0 ) {
-     level = 1;
-     cmask = 1 << 0;
-   } else if ( strcmp( cpu, "amd64-ssse3" ) == 0 ) {
-     level = 1;
-     cmask = 1 << 9;
-#endif
+#elif defined(VGP_amd64_linux)
+   if ( 0 == strcmp( arch, "x86"   ) ) return True;
+   if ( 0 == strcmp( arch, "amd64" ) ) return True;
+
+#elif defined(VGP_ppc32_linux)
+   if ( 0 == strcmp( arch, "ppc32" ) ) return True;
+
+#elif defined(VGP_ppc64_linux)
+   if ( 0 == strcmp( arch, "ppc64" ) ) return True;
+   if ( 0 == strcmp( arch, "ppc32" ) ) return True;
+
+#elif defined(VGP_ppc32_aix5) || defined(VGP_ppc64_aix5)
+   if (sizeof(void*) == 8) {
+      /* CPU is in 64-bit mode */
+      if ( 0 == strcmp( arch, "ppc64" ) ) return True;
+      if ( 0 == strcmp( arch, "ppc32" ) ) return True;
    } else {
-     return False;
+      if ( 0 == strcmp( arch, "ppc32" ) ) return True;
    }
 
-   assert( !(cmask != 0 && dmask != 0) );
-   assert( !(cmask == 0 && dmask == 0) );
+#else
+#  error Unknown platform
+#endif   // VGP_*
 
-   cpuid( level & 0x80000000, &a, &b, &c, &d );
-
-   if ( a >= level ) {
-      cpuid( level, &a, &b, &c, &d );
-
-      if (dmask > 0 && (d & dmask) != 0) return True;
-      if (cmask > 0 && (c & cmask) != 0) return True;
-   }
    return False;
 }
-#endif   // VGP_x86_linux  || VGP_amd64_linux
-
 
 //---------------------------------------------------------------------------
 // main
@@ -162,15 +69,15 @@
 {
    int i;
    if ( argc != 2 ) {
-      fprintf( stderr, "usage: arch_test <cpu-type>\n" );
-      exit( 2 );
+      fprintf( stderr, "usage: arch_test <arch-type>\n" );
+      exit(3);             // Usage error.
    }
    if (go( argv[1] )) {
-      return 0;      // matched
+      return 0;            // Matched.
    }
    for (i = 0; NULL != all_archs[i]; i++) {
-      if ( strcmp( argv[1], all_archs[i] ) == 0 )
-         return 1;
+      if ( 0 == strcmp( argv[1], all_archs[i] ) )
+         return 1;         // Didn't match, but named another arch.
    }
-   return 2;
+   return 2;               // Didn't match any archs.
 }
diff --git a/tests/os_test.c b/tests/os_test.c
new file mode 100644
index 0000000..065dbe5
--- /dev/null
+++ b/tests/os_test.c
@@ -0,0 +1,62 @@
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+// This program determines which OS that this Valgrind installation
+// supports, which depends on what was chosen at configure-time.
+//
+// We return:
+// - 0 if the machine matches the asked-for OS
+// - 1 if it doesn't match but does match the name of another OS
+// - 2 if it doesn't match the name of any OS
+// - 3 if there was a usage error (it also prints an error message)
+
+// Nb: When updating this file for a new OS, add the name to
+// 'all_OSes' as well as adding go().
+
+#define False  0
+#define True   1
+typedef int    Bool;
+
+char* all_OSes[] = {
+   "linux",
+   "aix5",
+   NULL
+};
+
+static Bool go(char* OS)
+{ 
+#if defined(VGO_linux)
+   if ( 0 == strcmp( OS, "linux" ) ) return True;
+
+#elif defined(VGO_aix5)
+   if ( 0 == strcmp( OS, "aix5"  ) ) return True;
+
+#else
+#  error Unknown OS
+#endif   // VGO_*
+
+   return False;
+}
+
+//---------------------------------------------------------------------------
+// main
+//---------------------------------------------------------------------------
+int main(int argc, char **argv)
+{
+   int i;
+   if ( argc != 2 ) {
+      fprintf( stderr, "usage: os_test <OS-type>\n" );
+      exit(3);             // Usage error.
+   }
+   if (go( argv[1] )) {
+      return 0;            // Matched.
+   }
+   for (i = 0; NULL != all_OSes[i]; i++) {
+      if ( 0 == strcmp( argv[1], all_OSes[i] ) )
+         return 1;         // Didn't match, but named another OS.
+   }
+   return 2;               // Didn't match any OSes.
+}
+
diff --git a/tests/os_test.in b/tests/os_test.in
deleted file mode 100644
index 27410dd..0000000
--- a/tests/os_test.in
+++ /dev/null
@@ -1,29 +0,0 @@
-#! /bin/sh
-
-# This script determines which OSes that this Valgrind installation
-# supports, which depends on the machine's OS.
-# We return:
-# - 0 if the machine matches the asked-for OS
-# - 1 if it didn't match, but did match the name of another OS
-# - 2 otherwise
-
-# Nb: When updating this file for a new OS, add the name to 'all_OSes'.
-
-all_OSes="linux aix5 darwin"
-
-if [ $# -ne 1 ] ; then
-    echo "usage: os_test <os-type>"
-    exit 2;
-fi
-
-if [ $1 = @VGCONF_OS@ ] ; then
-    exit 0;         # Matches this OS.
-fi
-
-for os in $all_OSes ; do
-    if [ $1 = $os ] ; then
-        exit 1;     # Matches another Valgrind-supported OS.
-    fi
-done
-
-exit 2;             # Doesn't match any Valgrind-supported OS.
diff --git a/tests/platform_test b/tests/platform_test
index e11d5d8..e91b9f7 100644
--- a/tests/platform_test
+++ b/tests/platform_test
@@ -13,7 +13,6 @@
 all_platforms=
 all_platforms="$all_platforms x86-linux amd64-linux ppc32-linux ppc64-linux"
 all_platforms="$all_platforms ppc32-aix5 ppc64-aix5"
-all_platforms="$all_platforms x86-darwin amd64-darwin"
 
 if [ $# -ne 2 ] ; then
     echo "usage: platform_test <arch-type> <OS-type>"
@@ -24,7 +23,7 @@
 # as the one holding this script.
 dir=`dirname $0`
 
-if $dir/arch_test $1 && sh $dir/os_test $2 ; then
+if $dir/arch_test $1 && $dir/os_test $2 ; then
     exit 0;         # Matches this platform.
 fi
 
diff --git a/tests/vg_regtest.in b/tests/vg_regtest.in
index bee87fc..8bcb050 100755
--- a/tests/vg_regtest.in
+++ b/tests/vg_regtest.in
@@ -67,13 +67,20 @@
 # one stderr.exp* file.  Any .exp* file that ends in '~' or '#' is ignored;
 # this is because Emacs creates temporary files of these names.
 #
-# The prerequisite command, if present, must return 0 otherwise the test is
-# skipped.  The post-test command, if present, must return 0 and its stdout
-# must match the expected stdout which is kept in <test>.post.exp*.
-#
 # If results don't match, the output can be found in <test>.std<strm>.out,
 # and the diff between expected and actual in <test>.std<strm>.diff*.
 #
+# The prerequisite command, if present, works like this:
+# - if it returns 0 the test is run
+# - if it returns 1 the test is skipped
+# - if it returns anything else the script aborts.
+# The idea here is results other than 0 or 1 are likely to be due to
+# problems with the commands, and you don't want to conflate them with the 1
+# case, which would happen if you just tested for zero or non-zero.
+#
+# The post-test command, if present, must return 0 and its stdout must match
+# the expected stdout which is kept in <test>.post.exp*.
+#
 # Sometimes it is useful to run all the tests at a high sanity check
 # level or with arbitrary other flags.  To make this simple, extra 
 # options, applied to all tests run, are read from $EXTRA_REGTEST_OPTS,
@@ -308,9 +315,18 @@
     read_vgtest_file($vgtest);
 
     if (defined $prereq) {
-        if (system("$prereq") != 0) {
+        my $prereq_res = system("$prereq");
+        if (0 == $prereq_res) {
+            # Do nothing (ie. continue with the test)
+        } elsif (256 == $prereq_res) {
+            # Nb: weird Perl-ism -- exit code of '1' is seen by Perl as 256...
+            # Prereq failed, skip.
             printf("%-16s (skipping, prereq failed: $prereq)\n", "$name:");
             return;
+        } else {
+            # Bad prereq; abort.
+            $prereq_res /= 256;
+            die "prereq returned $prereq_res: $prereq\n";
         }
     }
 
@@ -386,8 +402,8 @@
     # ppc/ directories ('arch_test' returns 1 for this case).  Likewise for
     # the OS and platform.
     # Nb: weird Perl-ism -- exit code of '1' is seen by Perl as 256...
-    if (256 == system(   "$tests_dir/tests/arch_test     $dir"))  { return; }
-    if (256 == system("sh $tests_dir/tests/os_test       $dir"))  { return; }
+    if (256 == system("$tests_dir/tests/arch_test $dir"))  { return; }
+    if (256 == system("$tests_dir/tests/os_test   $dir"))  { return; }
     if ($dir =~ /(\w+)-(\w+)/ &&
         256 == system("sh $tests_dir/tests/platform_test $1 $2")) { return; }