power_ISA2_05.c revision 9bea4c13fca0e3bb4b719dcb3ed63d47d479294e
1#include <stdio.h>
2
3double foo = -1.0;
4double FRT1;
5double FRT2;
6int base256(int val)
7{
8/* interpret the  bitstream representing val as a base 256 number for testing
9 * the parity instrs
10 */
11   int sum = 0;
12   int scale = 1;
13   int i;
14
15   for (i = 0; i < 8; i++) {
16      int bit = val & 1;
17      sum = sum + bit * scale;
18      val <<= 1;
19      scale *= 256;
20   }
21   return sum;
22}
23
24void test_parity_instrs()
25{
26   unsigned long long_word;
27   unsigned int word;
28   int i, parity;
29
30   for (i = 0; i < 50; i++) {
31      word = base256(i);
32      long_word = word;
33      __asm__ volatile ("prtyd %0, %1":"=r" (parity):"r"(long_word));
34      printf("prtyd (%x) => parity=%x\n", i, parity);
35      __asm__ volatile ("prtyw %0, %1":"=r" (parity):"r"(word));
36      printf("prtyw (%x) => parity=%x\n", i, parity);
37   }
38}
39
40void test_lfiwax()
41{
42   unsigned long base;
43   unsigned long offset;
44
45   typedef struct {
46      unsigned int hi;
47      unsigned int lo;
48   } int_pair_t;
49
50   int_pair_t *ip;
51   foo = -1024.0;
52   base = (unsigned long) &foo;
53   offset = 0;
54   __asm__ volatile ("lfiwax %0, %1, %2":"=f" (FRT1):"r"(base),
55                     "r"(offset));
56   ip = (int_pair_t *) & FRT1;
57   printf("lfiwax (%f) => FRT=(%x, %x)\n", foo, ip->hi, ip->lo);
58
59
60}
61
62
63
64/* lfdp FPp, DS(RA) : load float double pair
65** FPp	= leftmost 64 bits stored at DS(RA)
66** FPp+1= rightmost 64 bits stored at DS(RA)
67** FPp must be an even float register
68*/
69int test_double_pair_instrs()
70{
71   typedef struct {
72      double hi;
73      double lo;
74   } dbl_pair_t;
75
76   /* the following decls are for alignment */
77   int i;
78   int j;
79   int k;
80   int l;
81#ifdef __powerpc64__
82   int m;
83   int n;
84   int o;
85#endif
86   dbl_pair_t dbl_pair[3];      /* must be quad word aligned */
87   unsigned long base;
88   unsigned long offset;
89
90   for (i = 0; i < 3; i++) {
91      dbl_pair[i].hi = -1024.0 + i;
92      dbl_pair[i].lo = 1024.0 + i + 1;
93   }
94
95   __asm__ volatile ("lfdp 10, %0"::"m" (dbl_pair[0]));
96   __asm__ volatile ("fmr %0, 10":"=f" (FRT1));
97   __asm__ volatile ("fmr %0, 11":"=f" (FRT2));
98   printf("lfdp (%f, %f) => F_hi=%f, F_lo=%f\n",
99          dbl_pair[0].hi, dbl_pair[0].lo, FRT1, FRT2);
100
101
102   FRT1 = 2.2048;
103   FRT2 = -4.1024;
104   __asm__ volatile ("fmr 10, %0"::"f" (FRT1));
105   __asm__ volatile ("fmr 11, %0"::"f" (FRT2));
106   __asm__ volatile ("stfdp 10, %0"::"m" (dbl_pair[1]));
107   printf("stfdp (%f, %f) => F_hi=%f, F_lo=%f\n",
108          FRT1, FRT2, dbl_pair[1].hi, dbl_pair[1].lo);
109
110   FRT1 = 0.0;
111   FRT2 = -1.0;
112   base = (unsigned long) &dbl_pair;
113   offset = (unsigned long) &dbl_pair[1] - base;
114   __asm__ volatile ("or 20, 0, %0"::"r" (base));
115   __asm__ volatile ("or 21, 0, %0"::"r" (offset));
116   __asm__ volatile ("lfdpx 10, 20, 21");
117   __asm__ volatile ("fmr %0, 10":"=f" (FRT1));
118   __asm__ volatile ("fmr %0, 11":"=f" (FRT2));
119   printf("lfdpx (%f, %f) => F_hi=%f, F_lo=%f\n",
120          dbl_pair[1].hi, dbl_pair[1].lo, FRT1, FRT2);
121
122   FRT1 = 8.2048;
123   FRT2 = -16.1024;
124   base = (unsigned long) &dbl_pair;
125   offset = (unsigned long) &dbl_pair[2] - base;
126   __asm__ volatile ("or 20, 0, %0"::"r" (base));
127   __asm__ volatile ("or 21, 0, %0"::"r" (offset));
128   __asm__ volatile ("fmr %0, 10":"=f" (FRT1));
129   __asm__ volatile ("fmr %0, 11":"=f" (FRT2));
130   __asm__ volatile ("stfdpx 10, 20, 21");
131   printf("stfdpx (%f, %f) => F_hi=%f, F_lo=%f\n",
132          FRT1, FRT2, dbl_pair[2].hi, dbl_pair[2].lo);
133#ifdef __powerpc64__
134   return i + j + k + l + m + n + o;
135#else
136   return i + j + k + l;
137#endif
138}
139
140
141/* The contents of FRB with bit set 0 set to bit 0 of FRA copied into FRT */
142void test_fcpsgn()
143{
144   double A[] = {
145      10.101010,
146      -0.0,
147      0.0,
148      -10.101010
149   };
150
151   double B[] = {
152      11.111111,
153      -0.0,
154      0.0,
155      -11.111111
156   };
157
158   double FRT, FRA, FRB;
159   int i, j;
160
161   for (i = 0; i < 4; i++) {
162      FRA = A[i];
163      for (j = 0; j < 4; j++) {
164         FRB = B[j];
165         __asm__ volatile ("fcpsgn %0, %1, %2":"=f" (FRT):"f"(FRA),
166                           "f"(FRB));
167         printf("fcpsgn sign=%f, base=%f => %f\n", FRA, FRB, FRT);
168      }
169   }
170}
171
172/* b0 may be non-zero in lwarx/ldarx Power6 instrs */
173int test_reservation()
174{
175
176   int RT;
177   int i, j;
178   unsigned long base;
179   unsigned long offset;
180   long arr[4] = { 0xdeadbeef, 0xbad0beef, 0xbeefdead, 0xbeef0bad };
181
182
183   base = (unsigned long) &arr;
184   offset = (unsigned long) &arr[1] - base;
185   __asm__ volatile ("or 20, 0, %0"::"r" (base));
186   __asm__ volatile ("or 21, 0, %0"::"r" (offset));
187   __asm__ volatile ("lwarx %0, 20, 21, 1":"=r" (RT));
188   printf("lwarx => %x\n", RT);
189
190#ifdef __powerpc64__
191   offset = (unsigned long) &arr[1] - base;
192   __asm__ volatile ("or 21, 0, %0"::"r" (offset));
193   __asm__ volatile ("ldarx %0, 20, 21, 1":"=r" (RT));
194   printf("ldarx => %x\n", RT);
195#endif
196   return i + j;
197}
198
199int main(void)
200{
201   (void) test_reservation();
202   test_fcpsgn();
203   (void) test_double_pair_instrs();
204   test_lfiwax();
205   test_parity_instrs();
206   return 0;
207}
208