Home | History | Annotate | Download | only in ppc32
      1 
      2 #include <stdio.h>
      3 #include "tests/malloc.h"
      4 
      5 /* This is a Marie Celeste instruction.  Some IBM documents think it
      6    exists, others don't.  The same appears to be true for
      7    implementations - ppc970 doesn't think it exists, but POWER5
      8    does. */
      9 double do_fre ( double x )
     10 {
     11   double block[2];
     12   block[0] = x;
     13   __asm__ __volatile__(
     14      "lfd %%f1, 0(%0)\n\t"
     15      ".long 0xfc200830\n\t" /* == fre %%f1,%%f1 */
     16      "stfd %%f1, 8(%0)"
     17      : /*out*/
     18      : /*in*/ "b" (&block[0])
     19      : /*trash*/ "memory", "fr1"
     20   );
     21   return block[1];
     22 }
     23 
     24 double do_fres ( double x )
     25 {
     26   double block[2];
     27   block[0] = x;
     28   __asm__ __volatile__(
     29      "lfd %%f1, 0(%0)\n\t"
     30      "fres %%f1,%%f1\n\t"
     31      "stfd %%f1, 8(%0)"
     32      : /*out*/
     33      : /*in*/ "b" (&block[0])
     34      : /*trash*/ "memory", "fr1"
     35      );
     36   return block[1];
     37 }
     38 
     39 double do_frsqrte ( double x )
     40 {
     41   double block[2];
     42   block[0] = x;
     43   __asm__ __volatile__(
     44      "lfd %%f1, 0(%0)\n\t"
     45      "frsqrte %%f1,%%f1\n\t"
     46      "stfd %%f1, 8(%0)"
     47      : /*out*/
     48      : /*in*/ "b" (&block[0])
     49      : /*trash*/ "memory", "fr1"
     50      );
     51   return block[1];
     52 }
     53 
     54 /* Another Marie Celeste insn. */
     55 double do_frsqrtes ( double x )
     56 {
     57   double block[2];
     58   block[0] = x;
     59   __asm__ __volatile__(
     60      "lfd %%f1, 0(%0)\n\t"
     61      ".long 0xec200834\n\t" /* == frsqrtes %%f1,%%f1 */
     62      "stfd %%f1, 8(%0)"
     63      : /*out*/
     64      : /*in*/ "b" (&block[0])
     65      : /*trash*/ "memory", "fr1"
     66      );
     67   return block[1];
     68 }
     69 
     70 ////////////////////////////////////////////////////////////
     71 
     72 void do_one ( char* name,
     73               double(*f)(double),
     74               double* args, int nargs,
     75               char* argfmt, char* resfmt )
     76 {
     77   int i;
     78   double a, r;
     79   printf("\n");
     80 
     81   for (i = 0; i < nargs; i++) {
     82     a = args[i];
     83     r = f(a);
     84     printf("%s ", name);
     85     printf(argfmt, a);
     86     printf(" -> ");
     87     printf(resfmt, r);
     88     printf("\n");
     89   }
     90 }
     91 
     92 int main ( void )
     93 {
     94   int nargs = 19;
     95   double* args = malloc(nargs * sizeof(double));
     96   args[0]  =  0.0;
     97   args[1]  =  1.0 / 0.0; // inf
     98   args[2]  = -args[1]; //  -inf
     99   args[3]  = args[2]/args[2]; // nan
    100   args[4]  = -args[3]; // -nan
    101   args[5]  = -5e100;
    102   args[6]  = -5e20;
    103   args[7]  = -501.0;
    104   args[8]  = -6.0;
    105   args[9]  = -1.01;
    106   args[10] = -2e-20;
    107   args[11] = -2e-200;
    108   args[12] =  2e-200;
    109   args[13] =  2e-20;
    110   args[14] =  1.01;
    111   args[15] =  6.0;
    112   args[16] =  501.0;
    113   args[17] =  5e20;
    114   args[18] =  5e100;
    115 
    116   do_one( "fre",  do_fre,  args, nargs, "%e", "%4.1e");
    117   do_one( "fres", do_fres, args, nargs, "%e", "%4.1e");
    118 
    119   do_one( "frsqrte",  do_frsqrte,  args, nargs, "%e", "%4.1e");
    120   do_one( "frsqrtes", do_frsqrtes, args, nargs, "%e", "%4.1e");
    121 
    122   free(args);
    123   return 0;
    124 }
    125