From: Julian Seward Date: Sun, 29 Jan 2006 17:08:58 +0000 (+0000) Subject: Add test cases for soem FX (general-purpose) and GX (graphics) optional insns. X-Git-Tag: svn/VALGRIND_3_2_0~310 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=bb023d7227f0fb82b289927d1dfb05bd197029b1;p=thirdparty%2Fvalgrind.git Add test cases for soem FX (general-purpose) and GX (graphics) optional insns. git-svn-id: svn://svn.valgrind.org/valgrind/trunk@5601 --- diff --git a/none/tests/ppc32/test_fx.c b/none/tests/ppc32/test_fx.c new file mode 100644 index 0000000000..eda1b9200a --- /dev/null +++ b/none/tests/ppc32/test_fx.c @@ -0,0 +1,86 @@ + +#include +#include + +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 index 0000000000..0f6ac0e180 --- /dev/null +++ b/none/tests/ppc32/test_gx.c @@ -0,0 +1,124 @@ + +#include +#include + +/* 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; +}