]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
Add test cases for soem FX (general-purpose) and GX (graphics) optional insns.
authorJulian Seward <jseward@acm.org>
Sun, 29 Jan 2006 17:08:58 +0000 (17:08 +0000)
committerJulian Seward <jseward@acm.org>
Sun, 29 Jan 2006 17:08:58 +0000 (17:08 +0000)
git-svn-id: svn://svn.valgrind.org/valgrind/trunk@5601

none/tests/ppc32/test_fx.c [new file with mode: 0644]
none/tests/ppc32/test_gx.c [new file with mode: 0644]

diff --git a/none/tests/ppc32/test_fx.c b/none/tests/ppc32/test_fx.c
new file mode 100644 (file)
index 0000000..eda1b92
--- /dev/null
@@ -0,0 +1,86 @@
+
+#include <stdio.h>
+#include <malloc.h>
+
+double do_fsqrt ( double x )
+{
+  double block[2];
+  block[0] = x;
+  __asm__ __volatile__(
+     "lfd %%f1, 0(%0)\n\t"
+     "fsqrt %%f1,%%f1\n\t"
+     "stfd %%f1, 8(%0)"
+     : /*out*/
+     : /*in*/ "b" (&block[0])
+     : /*trash*/ "memory", "fr1"
+  );
+  return block[1];
+}
+
+double do_fsqrts ( double x )
+{
+  double block[2];
+  block[0] = x;
+  __asm__ __volatile__(
+     "lfd %%f1, 0(%0)\n\t"
+     "fsqrts %%f1,%%f1\n\t"
+     "stfd %%f1, 8(%0)"
+     : /*out*/
+     : /*in*/ "b" (&block[0])
+     : /*trash*/ "memory", "fr1"
+     );
+  return block[1];
+}
+
+////////////////////////////////////////////////////////////
+
+void do_one ( char* name, 
+              double(*f)(double), 
+              double* args, int nargs, 
+              char* argfmt, char* resfmt )
+{
+  int i;
+  double a, r;
+  printf("\n");
+
+  for (i = 0; i < nargs; i++) {
+    a = args[i];
+    r = f(a);
+    printf("%s ", name);
+    printf(argfmt, a);
+    printf(" -> ");
+    printf(resfmt, r);
+    printf("\n");
+  }
+}
+
+int main ( void )
+{
+  int nargs = 19;
+  double* args = malloc(nargs * sizeof(double));
+  args[0]  =  0.0;
+  args[1]  =  1.0 / 0.0; // inf
+  args[2]  = -args[1]; //  -inf
+  args[3]  = args[2]/args[2]; // nan
+  args[4]  = -args[3]; // -nan
+  args[5]  = -5e100;
+  args[6]  = -5e20;
+  args[7]  = -501.0;
+  args[8]  = -6.0;
+  args[9]  = -1.0;
+  args[10] = -2e-20;
+  args[11] = -2e-200;
+  args[12] =  2e-200;
+  args[13] =  2e-20;
+  args[14] =  1.0;
+  args[15] =  6.0;
+  args[16] =  501.0;
+  args[17] =  5e20;
+  args[18] =  5e100;
+
+  do_one( "fsqrt",  do_fsqrt,  args, nargs, "%e", "%20.14e");
+  do_one( "fsqrts", do_fsqrts, args, nargs, "%e", "%e");
+
+  free(args);
+  return 0;
+}
diff --git a/none/tests/ppc32/test_gx.c b/none/tests/ppc32/test_gx.c
new file mode 100644 (file)
index 0000000..0f6ac0e
--- /dev/null
@@ -0,0 +1,124 @@
+
+#include <stdio.h>
+#include <malloc.h>
+
+/* This is a Marie Celeste instruction.  Some IBM documents think it
+   exists, others don't.  The same appears to be true for
+   implementations - ppc970 doesn't think it exists, but POWER5
+   does. */
+double do_fre ( double x )
+{
+  double block[2];
+  block[0] = x;
+  __asm__ __volatile__(
+     "lfd %%f1, 0(%0)\n\t"
+     ".long 0xfc200830\n\t" /* == fre %%f1,%%f1 */
+     "stfd %%f1, 8(%0)"
+     : /*out*/
+     : /*in*/ "b" (&block[0])
+     : /*trash*/ "memory", "fr1"
+  );
+  return block[1];
+}
+
+double do_fres ( double x )
+{
+  double block[2];
+  block[0] = x;
+  __asm__ __volatile__(
+     "lfd %%f1, 0(%0)\n\t"
+     "fres %%f1,%%f1\n\t"
+     "stfd %%f1, 8(%0)"
+     : /*out*/
+     : /*in*/ "b" (&block[0])
+     : /*trash*/ "memory", "fr1"
+     );
+  return block[1];
+}
+
+double do_frsqrte ( double x )
+{
+  double block[2];
+  block[0] = x;
+  __asm__ __volatile__(
+     "lfd %%f1, 0(%0)\n\t"
+     "frsqrte %%f1,%%f1\n\t"
+     "stfd %%f1, 8(%0)"
+     : /*out*/
+     : /*in*/ "b" (&block[0])
+     : /*trash*/ "memory", "fr1"
+     );
+  return block[1];
+}
+
+/* Another Marie Celeste insn. */
+double do_frsqrtes ( double x )
+{
+  double block[2];
+  block[0] = x;
+  __asm__ __volatile__(
+     "lfd %%f1, 0(%0)\n\t"
+     ".long 0xec200834\n\t" /* == frsqrtes %%f1,%%f1 */
+     "stfd %%f1, 8(%0)"
+     : /*out*/
+     : /*in*/ "b" (&block[0])
+     : /*trash*/ "memory", "fr1"
+     );
+  return block[1];
+}
+
+////////////////////////////////////////////////////////////
+
+void do_one ( char* name, 
+              double(*f)(double), 
+              double* args, int nargs, 
+              char* argfmt, char* resfmt )
+{
+  int i;
+  double a, r;
+  printf("\n");
+
+  for (i = 0; i < nargs; i++) {
+    a = args[i];
+    r = f(a);
+    printf("%s ", name);
+    printf(argfmt, a);
+    printf(" -> ");
+    printf(resfmt, r);
+    printf("\n");
+  }
+}
+
+int main ( void )
+{
+  int nargs = 19;
+  double* args = malloc(nargs * sizeof(double));
+  args[0]  =  0.0;
+  args[1]  =  1.0 / 0.0; // inf
+  args[2]  = -args[1]; //  -inf
+  args[3]  = args[2]/args[2]; // nan
+  args[4]  = -args[3]; // -nan
+  args[5]  = -5e100;
+  args[6]  = -5e20;
+  args[7]  = -501.0;
+  args[8]  = -6.0;
+  args[9]  = -1.0;
+  args[10] = -2e-20;
+  args[11] = -2e-200;
+  args[12] =  2e-200;
+  args[13] =  2e-20;
+  args[14] =  1.0;
+  args[15] =  6.0;
+  args[16] =  501.0;
+  args[17] =  5e20;
+  args[18] =  5e100;
+
+  do_one( "fre",  do_fre,  args, nargs, "%e", "%e");
+  do_one( "fres", do_fres, args, nargs, "%e", "%e");
+
+  do_one( "frsqrte",  do_frsqrte,  args, nargs, "%e", "%e");
+  do_one( "frsqrtes", do_frsqrtes, args, nargs, "%e", "%e");
+
+  free(args);
+  return 0;
+}