test_gx.c revision ed07e00d438c74b7a23c01bfffde77e3968305e4
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. */
9double 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
24double 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
39double 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. */
55double 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
72void 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
92int 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