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#include <stdio.h>
209
210double foo = -1.0;
211double FRT1;
212double FRT2;
213int base256(int val)
214{
215/* interpret the  bitstream representing val as a base 256 number for testing
216 * the parity instrs
217 */
218   int sum = 0;
219   int scale = 1;
220   int i;
221
222   for (i = 0; i < 8; i++) {
223      int bit = val & 1;
224      sum = sum + bit * scale;
225      val <<= 1;
226      scale *= 256;
227   }
228   return sum;
229}
230
231void test_parity_instrs()
232{
233   unsigned long long_word;
234   unsigned int word;
235   int i, parity;
236
237   for (i = 0; i < 50; i++) {
238      word = base256(i);
239      long_word = word;
240      __asm__ volatile ("prtyd %0, %1":"=r" (parity):"r"(long_word));
241      printf("prtyd (%x) => parity=%x\n", i, parity);
242      __asm__ volatile ("prtyw %0, %1":"=r" (parity):"r"(word));
243      printf("prtyw (%x) => parity=%x\n", i, parity);
244   }
245}
246
247void test_lfiwax()
248{
249   unsigned long base;
250   unsigned long offset;
251
252   typedef struct {
253      unsigned int hi;
254      unsigned int lo;
255   } int_pair_t;
256
257   int_pair_t *ip;
258   foo = -1024.0;
259   base = (unsigned long) &foo;
260   offset = 0;
261   __asm__ volatile ("lfiwax %0, %1, %2":"=f" (FRT1):"r"(base),
262                     "r"(offset));
263   ip = (int_pair_t *) & FRT1;
264   printf("lfiwax (%f) => FRT=(%x, %x)\n", foo, ip->hi, ip->lo);
265
266
267}
268
269
270
271/* lfdp FPp, DS(RA) : load float double pair
272** FPp	= leftmost 64 bits stored at DS(RA)
273** FPp+1= rightmost 64 bits stored at DS(RA)
274** FPp must be an even float register
275*/
276int test_double_pair_instrs()
277{
278   typedef struct {
279      double hi;
280      double lo;
281   } dbl_pair_t;
282
283   /* the following decls are for alignment */
284   int i;
285   int j;
286   int k;
287   int l;
288#ifdef __powerpc64__
289   int m;
290   int n;
291   int o;
292#endif
293   dbl_pair_t dbl_pair[3];      /* must be quad word aligned */
294   unsigned long base;
295   unsigned long offset;
296
297   for (i = 0; i < 3; i++) {
298      dbl_pair[i].hi = -1024.0 + i;
299      dbl_pair[i].lo = 1024.0 + i + 1;
300   }
301
302   __asm__ volatile ("lfdp 10, %0"::"m" (dbl_pair[0]));
303   __asm__ volatile ("fmr %0, 10":"=f" (FRT1));
304   __asm__ volatile ("fmr %0, 11":"=f" (FRT2));
305   printf("lfdp (%f, %f) => F_hi=%f, F_lo=%f\n",
306          dbl_pair[0].hi, dbl_pair[0].lo, FRT1, FRT2);
307
308
309   FRT1 = 2.2048;
310   FRT2 = -4.1024;
311   __asm__ volatile ("fmr 10, %0"::"f" (FRT1));
312   __asm__ volatile ("fmr 11, %0"::"f" (FRT2));
313   __asm__ volatile ("stfdp 10, %0"::"m" (dbl_pair[1]));
314   printf("stfdp (%f, %f) => F_hi=%f, F_lo=%f\n",
315          FRT1, FRT2, dbl_pair[1].hi, dbl_pair[1].lo);
316
317   FRT1 = 0.0;
318   FRT2 = -1.0;
319   base = (unsigned long) &dbl_pair;
320   offset = (unsigned long) &dbl_pair[1] - base;
321   __asm__ volatile ("or 20, 0, %0"::"r" (base));
322   __asm__ volatile ("or 21, 0, %0"::"r" (offset));
323   __asm__ volatile ("lfdpx 10, 20, 21");
324   __asm__ volatile ("fmr %0, 10":"=f" (FRT1));
325   __asm__ volatile ("fmr %0, 11":"=f" (FRT2));
326   printf("lfdpx (%f, %f) => F_hi=%f, F_lo=%f\n",
327          dbl_pair[1].hi, dbl_pair[1].lo, FRT1, FRT2);
328
329   FRT1 = 8.2048;
330   FRT2 = -16.1024;
331   base = (unsigned long) &dbl_pair;
332   offset = (unsigned long) &dbl_pair[2] - base;
333   __asm__ volatile ("or 20, 0, %0"::"r" (base));
334   __asm__ volatile ("or 21, 0, %0"::"r" (offset));
335   __asm__ volatile ("fmr %0, 10":"=f" (FRT1));
336   __asm__ volatile ("fmr %0, 11":"=f" (FRT2));
337   __asm__ volatile ("stfdpx 10, 20, 21");
338   printf("stfdpx (%f, %f) => F_hi=%f, F_lo=%f\n",
339          FRT1, FRT2, dbl_pair[2].hi, dbl_pair[2].lo);
340#ifdef __powerpc64__
341   return i + j + k + l + m + n + o;
342#else
343   return i + j + k + l;
344#endif
345}
346
347
348/* The contents of FRB with bit set 0 set to bit 0 of FRA copied into FRT */
349void test_fcpsgn()
350{
351   double A[] = {
352      10.101010,
353      -0.0,
354      0.0,
355      -10.101010
356   };
357
358   double B[] = {
359      11.111111,
360      -0.0,
361      0.0,
362      -11.111111
363   };
364
365   double FRT, FRA, FRB;
366   int i, j;
367
368   for (i = 0; i < 4; i++) {
369      FRA = A[i];
370      for (j = 0; j < 4; j++) {
371         FRB = B[j];
372         __asm__ volatile ("fcpsgn %0, %1, %2":"=f" (FRT):"f"(FRA),
373                           "f"(FRB));
374         printf("fcpsgn sign=%f, base=%f => %f\n", FRA, FRB, FRT);
375      }
376   }
377}
378
379/* b0 may be non-zero in lwarx/ldarx Power6 instrs */
380int test_reservation()
381{
382
383   int RT;
384   int i, j;
385   unsigned long base;
386   unsigned long offset;
387   long arr[4] = { 0xdeadbeef, 0xbad0beef, 0xbeefdead, 0xbeef0bad };
388
389
390   base = (unsigned long) &arr;
391   offset = (unsigned long) &arr[1] - base;
392   __asm__ volatile ("or 20, 0, %0"::"r" (base));
393   __asm__ volatile ("or 21, 0, %0"::"r" (offset));
394   __asm__ volatile ("lwarx %0, 20, 21, 1":"=r" (RT));
395   printf("lwarx => %x\n", RT);
396
397#ifdef __powerpc64__
398   offset = (unsigned long) &arr[1] - base;
399   __asm__ volatile ("or 21, 0, %0"::"r" (offset));
400   __asm__ volatile ("ldarx %0, 20, 21, 1":"=r" (RT));
401   printf("ldarx => %x\n", RT);
402#endif
403   return i + j;
404}
405
406int main(void)
407{
408   (void) test_reservation();
409   test_fcpsgn();
410   (void) test_double_pair_instrs();
411   test_lfiwax();
412   test_parity_instrs();
413   return 0;
414}
415#include <stdio.h>
416
417double foo = -1.0;
418double FRT1;
419double FRT2;
420int base256(int val)
421{
422/* interpret the  bitstream representing val as a base 256 number for testing
423 * the parity instrs
424 */
425   int sum = 0;
426   int scale = 1;
427   int i;
428
429   for (i = 0; i < 8; i++) {
430      int bit = val & 1;
431      sum = sum + bit * scale;
432      val <<= 1;
433      scale *= 256;
434   }
435   return sum;
436}
437
438void test_parity_instrs()
439{
440   unsigned long long_word;
441   unsigned int word;
442   int i, parity;
443
444   for (i = 0; i < 50; i++) {
445      word = base256(i);
446      long_word = word;
447      __asm__ volatile ("prtyd %0, %1":"=r" (parity):"r"(long_word));
448      printf("prtyd (%x) => parity=%x\n", i, parity);
449      __asm__ volatile ("prtyw %0, %1":"=r" (parity):"r"(word));
450      printf("prtyw (%x) => parity=%x\n", i, parity);
451   }
452}
453
454void test_lfiwax()
455{
456   unsigned long base;
457   unsigned long offset;
458
459   typedef struct {
460      unsigned int hi;
461      unsigned int lo;
462   } int_pair_t;
463
464   int_pair_t *ip;
465   foo = -1024.0;
466   base = (unsigned long) &foo;
467   offset = 0;
468   __asm__ volatile ("lfiwax %0, %1, %2":"=f" (FRT1):"r"(base),
469                     "r"(offset));
470   ip = (int_pair_t *) & FRT1;
471   printf("lfiwax (%f) => FRT=(%x, %x)\n", foo, ip->hi, ip->lo);
472
473
474}
475
476
477
478/* lfdp FPp, DS(RA) : load float double pair
479** FPp	= leftmost 64 bits stored at DS(RA)
480** FPp+1= rightmost 64 bits stored at DS(RA)
481** FPp must be an even float register
482*/
483int test_double_pair_instrs()
484{
485   typedef struct {
486      double hi;
487      double lo;
488   } dbl_pair_t;
489
490   /* the following decls are for alignment */
491   int i;
492   int j;
493   int k;
494   int l;
495#ifdef __powerpc64__
496   int m;
497   int n;
498   int o;
499#endif
500   dbl_pair_t dbl_pair[3];      /* must be quad word aligned */
501   unsigned long base;
502   unsigned long offset;
503
504   for (i = 0; i < 3; i++) {
505      dbl_pair[i].hi = -1024.0 + i;
506      dbl_pair[i].lo = 1024.0 + i + 1;
507   }
508
509   __asm__ volatile ("lfdp 10, %0"::"m" (dbl_pair[0]));
510   __asm__ volatile ("fmr %0, 10":"=f" (FRT1));
511   __asm__ volatile ("fmr %0, 11":"=f" (FRT2));
512   printf("lfdp (%f, %f) => F_hi=%f, F_lo=%f\n",
513          dbl_pair[0].hi, dbl_pair[0].lo, FRT1, FRT2);
514
515
516   FRT1 = 2.2048;
517   FRT2 = -4.1024;
518   __asm__ volatile ("fmr 10, %0"::"f" (FRT1));
519   __asm__ volatile ("fmr 11, %0"::"f" (FRT2));
520   __asm__ volatile ("stfdp 10, %0"::"m" (dbl_pair[1]));
521   printf("stfdp (%f, %f) => F_hi=%f, F_lo=%f\n",
522          FRT1, FRT2, dbl_pair[1].hi, dbl_pair[1].lo);
523
524   FRT1 = 0.0;
525   FRT2 = -1.0;
526   base = (unsigned long) &dbl_pair;
527   offset = (unsigned long) &dbl_pair[1] - base;
528   __asm__ volatile ("or 20, 0, %0"::"r" (base));
529   __asm__ volatile ("or 21, 0, %0"::"r" (offset));
530   __asm__ volatile ("lfdpx 10, 20, 21");
531   __asm__ volatile ("fmr %0, 10":"=f" (FRT1));
532   __asm__ volatile ("fmr %0, 11":"=f" (FRT2));
533   printf("lfdpx (%f, %f) => F_hi=%f, F_lo=%f\n",
534          dbl_pair[1].hi, dbl_pair[1].lo, FRT1, FRT2);
535
536   FRT1 = 8.2048;
537   FRT2 = -16.1024;
538   base = (unsigned long) &dbl_pair;
539   offset = (unsigned long) &dbl_pair[2] - base;
540   __asm__ volatile ("or 20, 0, %0"::"r" (base));
541   __asm__ volatile ("or 21, 0, %0"::"r" (offset));
542   __asm__ volatile ("fmr %0, 10":"=f" (FRT1));
543   __asm__ volatile ("fmr %0, 11":"=f" (FRT2));
544   __asm__ volatile ("stfdpx 10, 20, 21");
545   printf("stfdpx (%f, %f) => F_hi=%f, F_lo=%f\n",
546          FRT1, FRT2, dbl_pair[2].hi, dbl_pair[2].lo);
547#ifdef __powerpc64__
548   return i + j + k + l + m + n + o;
549#else
550   return i + j + k + l;
551#endif
552}
553
554
555/* The contents of FRB with bit set 0 set to bit 0 of FRA copied into FRT */
556void test_fcpsgn()
557{
558   double A[] = {
559      10.101010,
560      -0.0,
561      0.0,
562      -10.101010
563   };
564
565   double B[] = {
566      11.111111,
567      -0.0,
568      0.0,
569      -11.111111
570   };
571
572   double FRT, FRA, FRB;
573   int i, j;
574
575   for (i = 0; i < 4; i++) {
576      FRA = A[i];
577      for (j = 0; j < 4; j++) {
578         FRB = B[j];
579         __asm__ volatile ("fcpsgn %0, %1, %2":"=f" (FRT):"f"(FRA),
580                           "f"(FRB));
581         printf("fcpsgn sign=%f, base=%f => %f\n", FRA, FRB, FRT);
582      }
583   }
584}
585
586/* b0 may be non-zero in lwarx/ldarx Power6 instrs */
587int test_reservation()
588{
589
590   int RT;
591   int i, j;
592   unsigned long base;
593   unsigned long offset;
594   long arr[4] = { 0xdeadbeef, 0xbad0beef, 0xbeefdead, 0xbeef0bad };
595
596
597   base = (unsigned long) &arr;
598   offset = (unsigned long) &arr[1] - base;
599   __asm__ volatile ("or 20, 0, %0"::"r" (base));
600   __asm__ volatile ("or 21, 0, %0"::"r" (offset));
601   __asm__ volatile ("lwarx %0, 20, 21, 1":"=r" (RT));
602   printf("lwarx => %x\n", RT);
603
604#ifdef __powerpc64__
605   offset = (unsigned long) &arr[1] - base;
606   __asm__ volatile ("or 21, 0, %0"::"r" (offset));
607   __asm__ volatile ("ldarx %0, 20, 21, 1":"=r" (RT));
608   printf("ldarx => %x\n", RT);
609#endif
610   return i + j;
611}
612
613int main(void)
614{
615   (void) test_reservation();
616   test_fcpsgn();
617   (void) test_double_pair_instrs();
618   test_lfiwax();
619   test_parity_instrs();
620   return 0;
621}
622#include <stdio.h>
623
624double foo = -1.0;
625double FRT1;
626double FRT2;
627int base256(int val)
628{
629/* interpret the  bitstream representing val as a base 256 number for testing
630 * the parity instrs
631 */
632   int sum = 0;
633   int scale = 1;
634   int i;
635
636   for (i = 0; i < 8; i++) {
637      int bit = val & 1;
638      sum = sum + bit * scale;
639      val <<= 1;
640      scale *= 256;
641   }
642   return sum;
643}
644
645void test_parity_instrs()
646{
647   unsigned long long_word;
648   unsigned int word;
649   int i, parity;
650
651   for (i = 0; i < 50; i++) {
652      word = base256(i);
653      long_word = word;
654      __asm__ volatile ("prtyd %0, %1":"=r" (parity):"r"(long_word));
655      printf("prtyd (%x) => parity=%x\n", i, parity);
656      __asm__ volatile ("prtyw %0, %1":"=r" (parity):"r"(word));
657      printf("prtyw (%x) => parity=%x\n", i, parity);
658   }
659}
660
661void test_lfiwax()
662{
663   unsigned long base;
664   unsigned long offset;
665
666   typedef struct {
667      unsigned int hi;
668      unsigned int lo;
669   } int_pair_t;
670
671   int_pair_t *ip;
672   foo = -1024.0;
673   base = (unsigned long) &foo;
674   offset = 0;
675   __asm__ volatile ("lfiwax %0, %1, %2":"=f" (FRT1):"r"(base),
676                     "r"(offset));
677   ip = (int_pair_t *) & FRT1;
678   printf("lfiwax (%f) => FRT=(%x, %x)\n", foo, ip->hi, ip->lo);
679
680
681}
682
683
684
685/* lfdp FPp, DS(RA) : load float double pair
686** FPp	= leftmost 64 bits stored at DS(RA)
687** FPp+1= rightmost 64 bits stored at DS(RA)
688** FPp must be an even float register
689*/
690int test_double_pair_instrs()
691{
692   typedef struct {
693      double hi;
694      double lo;
695   } dbl_pair_t;
696
697   /* the following decls are for alignment */
698   int i;
699   int j;
700   int k;
701   int l;
702#ifdef __powerpc64__
703   int m;
704   int n;
705   int o;
706#endif
707   dbl_pair_t dbl_pair[3];      /* must be quad word aligned */
708   unsigned long base;
709   unsigned long offset;
710
711   for (i = 0; i < 3; i++) {
712      dbl_pair[i].hi = -1024.0 + i;
713      dbl_pair[i].lo = 1024.0 + i + 1;
714   }
715
716   __asm__ volatile ("lfdp 10, %0"::"m" (dbl_pair[0]));
717   __asm__ volatile ("fmr %0, 10":"=f" (FRT1));
718   __asm__ volatile ("fmr %0, 11":"=f" (FRT2));
719   printf("lfdp (%f, %f) => F_hi=%f, F_lo=%f\n",
720          dbl_pair[0].hi, dbl_pair[0].lo, FRT1, FRT2);
721
722
723   FRT1 = 2.2048;
724   FRT2 = -4.1024;
725   __asm__ volatile ("fmr 10, %0"::"f" (FRT1));
726   __asm__ volatile ("fmr 11, %0"::"f" (FRT2));
727   __asm__ volatile ("stfdp 10, %0"::"m" (dbl_pair[1]));
728   printf("stfdp (%f, %f) => F_hi=%f, F_lo=%f\n",
729          FRT1, FRT2, dbl_pair[1].hi, dbl_pair[1].lo);
730
731   FRT1 = 0.0;
732   FRT2 = -1.0;
733   base = (unsigned long) &dbl_pair;
734   offset = (unsigned long) &dbl_pair[1] - base;
735   __asm__ volatile ("or 20, 0, %0"::"r" (base));
736   __asm__ volatile ("or 21, 0, %0"::"r" (offset));
737   __asm__ volatile ("lfdpx 10, 20, 21");
738   __asm__ volatile ("fmr %0, 10":"=f" (FRT1));
739   __asm__ volatile ("fmr %0, 11":"=f" (FRT2));
740   printf("lfdpx (%f, %f) => F_hi=%f, F_lo=%f\n",
741          dbl_pair[1].hi, dbl_pair[1].lo, FRT1, FRT2);
742
743   FRT1 = 8.2048;
744   FRT2 = -16.1024;
745   base = (unsigned long) &dbl_pair;
746   offset = (unsigned long) &dbl_pair[2] - base;
747   __asm__ volatile ("or 20, 0, %0"::"r" (base));
748   __asm__ volatile ("or 21, 0, %0"::"r" (offset));
749   __asm__ volatile ("fmr %0, 10":"=f" (FRT1));
750   __asm__ volatile ("fmr %0, 11":"=f" (FRT2));
751   __asm__ volatile ("stfdpx 10, 20, 21");
752   printf("stfdpx (%f, %f) => F_hi=%f, F_lo=%f\n",
753          FRT1, FRT2, dbl_pair[2].hi, dbl_pair[2].lo);
754#ifdef __powerpc64__
755   return i + j + k + l + m + n + o;
756#else
757   return i + j + k + l;
758#endif
759}
760
761
762/* The contents of FRB with bit set 0 set to bit 0 of FRA copied into FRT */
763void test_fcpsgn()
764{
765   double A[] = {
766      10.101010,
767      -0.0,
768      0.0,
769      -10.101010
770   };
771
772   double B[] = {
773      11.111111,
774      -0.0,
775      0.0,
776      -11.111111
777   };
778
779   double FRT, FRA, FRB;
780   int i, j;
781
782   for (i = 0; i < 4; i++) {
783      FRA = A[i];
784      for (j = 0; j < 4; j++) {
785         FRB = B[j];
786         __asm__ volatile ("fcpsgn %0, %1, %2":"=f" (FRT):"f"(FRA),
787                           "f"(FRB));
788         printf("fcpsgn sign=%f, base=%f => %f\n", FRA, FRB, FRT);
789      }
790   }
791}
792
793/* b0 may be non-zero in lwarx/ldarx Power6 instrs */
794int test_reservation()
795{
796
797   int RT;
798   int i, j;
799   unsigned long base;
800   unsigned long offset;
801   long arr[4] = { 0xdeadbeef, 0xbad0beef, 0xbeefdead, 0xbeef0bad };
802
803
804   base = (unsigned long) &arr;
805   offset = (unsigned long) &arr[1] - base;
806   __asm__ volatile ("or 20, 0, %0"::"r" (base));
807   __asm__ volatile ("or 21, 0, %0"::"r" (offset));
808   __asm__ volatile ("lwarx %0, 20, 21, 1":"=r" (RT));
809   printf("lwarx => %x\n", RT);
810
811#ifdef __powerpc64__
812   offset = (unsigned long) &arr[1] - base;
813   __asm__ volatile ("or 21, 0, %0"::"r" (offset));
814   __asm__ volatile ("ldarx %0, 20, 21, 1":"=r" (RT));
815   printf("ldarx => %x\n", RT);
816#endif
817   return i + j;
818}
819
820int main(void)
821{
822   (void) test_reservation();
823   test_fcpsgn();
824   (void) test_double_pair_instrs();
825   test_lfiwax();
826   test_parity_instrs();
827   return 0;
828}
829#include <stdio.h>
830
831double foo = -1.0;
832double FRT1;
833double FRT2;
834int base256(int val)
835{
836/* interpret the  bitstream representing val as a base 256 number for testing
837 * the parity instrs
838 */
839   int sum = 0;
840   int scale = 1;
841   int i;
842
843   for (i = 0; i < 8; i++) {
844      int bit = val & 1;
845      sum = sum + bit * scale;
846      val <<= 1;
847      scale *= 256;
848   }
849   return sum;
850}
851
852void test_parity_instrs()
853{
854   unsigned long long_word;
855   unsigned int word;
856   int i, parity;
857
858   for (i = 0; i < 50; i++) {
859      word = base256(i);
860      long_word = word;
861      __asm__ volatile ("prtyd %0, %1":"=r" (parity):"r"(long_word));
862      printf("prtyd (%x) => parity=%x\n", i, parity);
863      __asm__ volatile ("prtyw %0, %1":"=r" (parity):"r"(word));
864      printf("prtyw (%x) => parity=%x\n", i, parity);
865   }
866}
867
868void test_lfiwax()
869{
870   unsigned long base;
871   unsigned long offset;
872
873   typedef struct {
874      unsigned int hi;
875      unsigned int lo;
876   } int_pair_t;
877
878   int_pair_t *ip;
879   foo = -1024.0;
880   base = (unsigned long) &foo;
881   offset = 0;
882   __asm__ volatile ("lfiwax %0, %1, %2":"=f" (FRT1):"r"(base),
883                     "r"(offset));
884   ip = (int_pair_t *) & FRT1;
885   printf("lfiwax (%f) => FRT=(%x, %x)\n", foo, ip->hi, ip->lo);
886
887
888}
889
890
891
892/* lfdp FPp, DS(RA) : load float double pair
893** FPp	= leftmost 64 bits stored at DS(RA)
894** FPp+1= rightmost 64 bits stored at DS(RA)
895** FPp must be an even float register
896*/
897int test_double_pair_instrs()
898{
899   typedef struct {
900      double hi;
901      double lo;
902   } dbl_pair_t;
903
904   /* the following decls are for alignment */
905   int i;
906   int j;
907   int k;
908   int l;
909#ifdef __powerpc64__
910   int m;
911   int n;
912   int o;
913#endif
914   dbl_pair_t dbl_pair[3];      /* must be quad word aligned */
915   unsigned long base;
916   unsigned long offset;
917
918   for (i = 0; i < 3; i++) {
919      dbl_pair[i].hi = -1024.0 + i;
920      dbl_pair[i].lo = 1024.0 + i + 1;
921   }
922
923   __asm__ volatile ("lfdp 10, %0"::"m" (dbl_pair[0]));
924   __asm__ volatile ("fmr %0, 10":"=f" (FRT1));
925   __asm__ volatile ("fmr %0, 11":"=f" (FRT2));
926   printf("lfdp (%f, %f) => F_hi=%f, F_lo=%f\n",
927          dbl_pair[0].hi, dbl_pair[0].lo, FRT1, FRT2);
928
929
930   FRT1 = 2.2048;
931   FRT2 = -4.1024;
932   __asm__ volatile ("fmr 10, %0"::"f" (FRT1));
933   __asm__ volatile ("fmr 11, %0"::"f" (FRT2));
934   __asm__ volatile ("stfdp 10, %0"::"m" (dbl_pair[1]));
935   printf("stfdp (%f, %f) => F_hi=%f, F_lo=%f\n",
936          FRT1, FRT2, dbl_pair[1].hi, dbl_pair[1].lo);
937
938   FRT1 = 0.0;
939   FRT2 = -1.0;
940   base = (unsigned long) &dbl_pair;
941   offset = (unsigned long) &dbl_pair[1] - base;
942   __asm__ volatile ("or 20, 0, %0"::"r" (base));
943   __asm__ volatile ("or 21, 0, %0"::"r" (offset));
944   __asm__ volatile ("lfdpx 10, 20, 21");
945   __asm__ volatile ("fmr %0, 10":"=f" (FRT1));
946   __asm__ volatile ("fmr %0, 11":"=f" (FRT2));
947   printf("lfdpx (%f, %f) => F_hi=%f, F_lo=%f\n",
948          dbl_pair[1].hi, dbl_pair[1].lo, FRT1, FRT2);
949
950   FRT1 = 8.2048;
951   FRT2 = -16.1024;
952   base = (unsigned long) &dbl_pair;
953   offset = (unsigned long) &dbl_pair[2] - base;
954   __asm__ volatile ("or 20, 0, %0"::"r" (base));
955   __asm__ volatile ("or 21, 0, %0"::"r" (offset));
956   __asm__ volatile ("fmr %0, 10":"=f" (FRT1));
957   __asm__ volatile ("fmr %0, 11":"=f" (FRT2));
958   __asm__ volatile ("stfdpx 10, 20, 21");
959   printf("stfdpx (%f, %f) => F_hi=%f, F_lo=%f\n",
960          FRT1, FRT2, dbl_pair[2].hi, dbl_pair[2].lo);
961#ifdef __powerpc64__
962   return i + j + k + l + m + n + o;
963#else
964   return i + j + k + l;
965#endif
966}
967
968
969/* The contents of FRB with bit set 0 set to bit 0 of FRA copied into FRT */
970void test_fcpsgn()
971{
972   double A[] = {
973      10.101010,
974      -0.0,
975      0.0,
976      -10.101010
977   };
978
979   double B[] = {
980      11.111111,
981      -0.0,
982      0.0,
983      -11.111111
984   };
985
986   double FRT, FRA, FRB;
987   int i, j;
988
989   for (i = 0; i < 4; i++) {
990      FRA = A[i];
991      for (j = 0; j < 4; j++) {
992         FRB = B[j];
993         __asm__ volatile ("fcpsgn %0, %1, %2":"=f" (FRT):"f"(FRA),
994                           "f"(FRB));
995         printf("fcpsgn sign=%f, base=%f => %f\n", FRA, FRB, FRT);
996      }
997   }
998}
999
1000/* b0 may be non-zero in lwarx/ldarx Power6 instrs */
1001int test_reservation()
1002{
1003
1004   int RT;
1005   int i, j;
1006   unsigned long base;
1007   unsigned long offset;
1008   long arr[4] = { 0xdeadbeef, 0xbad0beef, 0xbeefdead, 0xbeef0bad };
1009
1010
1011   base = (unsigned long) &arr;
1012   offset = (unsigned long) &arr[1] - base;
1013   __asm__ volatile ("or 20, 0, %0"::"r" (base));
1014   __asm__ volatile ("or 21, 0, %0"::"r" (offset));
1015   __asm__ volatile ("lwarx %0, 20, 21, 1":"=r" (RT));
1016   printf("lwarx => %x\n", RT);
1017
1018#ifdef __powerpc64__
1019   offset = (unsigned long) &arr[1] - base;
1020   __asm__ volatile ("or 21, 0, %0"::"r" (offset));
1021   __asm__ volatile ("ldarx %0, 20, 21, 1":"=r" (RT));
1022   printf("ldarx => %x\n", RT);
1023#endif
1024   return i + j;
1025}
1026
1027int main(void)
1028{
1029   (void) test_reservation();
1030   test_fcpsgn();
1031   (void) test_double_pair_instrs();
1032   test_lfiwax();
1033   test_parity_instrs();
1034   return 0;
1035}
1036