1 #include <stdio.h>
2 #include <config.h>
3 
4 double foo = -1.0;
5 double FRT1;
6 double FRT2;
base256(int val)7 int base256(int val)
8 {
9 /* interpret the  bitstream representing val as a base 256 number for testing
10  * the parity instrs
11  */
12    int sum = 0;
13    int scale = 1;
14    int i;
15 
16    for (i = 0; i < 8; i++) {
17       int bit = val & 1;
18       sum = sum + bit * scale;
19       val <<= 1;
20       scale *= 256;
21    }
22    return sum;
23 }
24 
test_parity_instrs()25 void test_parity_instrs()
26 {
27    unsigned long long_word;
28    unsigned int word;
29    int i, parity;
30 
31    for (i = 0; i < 50; i++) {
32       word = base256(i);
33       long_word = word;
34       __asm__ volatile ("prtyd %0, %1":"=r" (parity):"r"(long_word));
35       printf("prtyd (%x) => parity=%x\n", i, parity);
36       __asm__ volatile ("prtyw %0, %1":"=r" (parity):"r"(word));
37       printf("prtyw (%x) => parity=%x\n", i, parity);
38    }
39 }
40 
test_lfiwax()41 void test_lfiwax()
42 {
43    unsigned long base;
44    float foo_s;
45 
46    typedef struct {
47 #if defined(VGP_ppc64le_linux)
48       unsigned int lo;
49       unsigned int hi;
50 #else
51       unsigned int hi;
52       unsigned int lo;
53 #endif
54    } int_pair_t;
55 
56    int_pair_t *ip;
57    foo_s = -1024.0;
58    base = (unsigned long) &foo_s;
59 
60    __asm__ volatile ("lfiwax %0, 0, %1":"=f" (FRT1):"r"(base));
61    ip = (int_pair_t *) & FRT1;
62    printf("lfiwax (%f) => FRT=(%x, %x)\n", foo_s, ip->hi, ip->lo);
63 
64 
65 }
66 
67 
68 
69 /* lfdp FPp, DS(RA) : load float double pair
70 ** FPp	= leftmost 64 bits stored at DS(RA)
71 ** FPp+1= rightmost 64 bits stored at DS(RA)
72 ** FPp must be an even float register
73 **
74 ** The [st|l]fdp[x] instructions were put into the "Floating-Point.Phased-Out"
75 ** category in ISA 2.06 (i.e., POWER7 timeframe).  If valgrind and its
76 ** testsuite are built with -mcpu=power7 (or later), then the assembler will
77 ** not recognize those phased out instructions.
78 **
79 */
test_double_pair_instrs()80 void test_double_pair_instrs()
81 {
82 #ifdef HAVE_AS_PPC_FPPO
83    typedef struct {
84       double hi;
85       double lo;
86    } dbl_pair_t;
87 
88    /* the following decls are for alignment */
89    int i;
90    dbl_pair_t dbl_pair[3];      /* must be quad word aligned */
91    unsigned long base;
92    unsigned long offset;
93 
94    for (i = 0; i < 3; i++) {
95       dbl_pair[i].hi = -1024.0 + i;
96       dbl_pair[i].lo = 1024.0 + i + 1;
97    }
98 
99    __asm__ volatile ("lfdp 10, %0"::"m" (dbl_pair[0]));
100    __asm__ volatile ("fmr %0, 10":"=d" (FRT1));
101    __asm__ volatile ("fmr %0, 11":"=d" (FRT2));
102    printf("lfdp (%lf, %lf) => F_hi=%lf, F_lo=%lf\n",
103           dbl_pair[0].hi, dbl_pair[0].lo, FRT1, FRT2);
104 
105 
106    FRT1 = 2.2048;
107    FRT2 = -4.1024;
108    __asm__ volatile ("fmr 10, %0"::"d" (FRT1));
109    __asm__ volatile ("fmr 11, %0"::"d" (FRT2));
110    __asm__ volatile ("stfdp 10, %0"::"m" (dbl_pair[1]));
111    printf("stfdp (%lf, %lf) => F_hi=%lf, F_lo=%lf\n",
112           FRT1, FRT2, dbl_pair[1].hi, dbl_pair[1].lo);
113 
114    FRT1 = 0.0;
115    FRT2 = -1.0;
116    base = (unsigned long) &dbl_pair;
117    offset = (unsigned long) &dbl_pair[1] - base;
118    __asm__ volatile ("ori 20, %0, 0"::"r" (base));
119    __asm__ volatile ("ori 21, %0, 0"::"r" (offset));
120    __asm__ volatile ("lfdpx 10, 20, 21");
121    __asm__ volatile ("fmr %0, 10":"=d" (FRT1));
122    __asm__ volatile ("fmr %0, 11":"=d" (FRT2));
123    printf("lfdpx (%lf, %lf) => F_hi=%lf, F_lo=%lf\n",
124           dbl_pair[1].hi, dbl_pair[1].lo, FRT1, FRT2);
125 
126    FRT1 = 8.2048;
127    FRT2 = -16.1024;
128    base = (unsigned long) &dbl_pair;
129    offset = (unsigned long) &dbl_pair[2] - base;
130    __asm__ volatile ("ori 20, %0, 0"::"r" (base));
131    __asm__ volatile ("ori 21, %0, 0"::"r" (offset));
132    __asm__ volatile ("fmr 10, %0 "::"d" (FRT1));
133    __asm__ volatile ("fmr 11, %0 "::"d" (FRT2));
134    __asm__ volatile ("stfdpx 10, 20, 21");
135    printf("stfdpx (%lf, %lf) => F_hi=%lf, F_lo=%lf\n",
136           FRT1, FRT2, dbl_pair[2].hi, dbl_pair[2].lo);
137 #endif
138 }
139 
140 
141 /* The contents of FRB with bit set 0 set to bit 0 of FRA copied into FRT */
test_fcpsgn()142 void 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 */
test_reservation()173 void test_reservation()
174 {
175 
176    unsigned long long RT;
177    unsigned long base;
178    unsigned long offset;
179    long arrL[] __attribute__ ((aligned (8))) = { 0xdeadbeef00112233ULL, 0xbad0beef44556677ULL, 0xbeefdead8899aabbULL, 0xbeef0badccddeeffULL };
180    int arrI[] __attribute__ ((aligned (4))) = { 0xdeadbeef, 0xbad0beef, 0xbeefdead, 0xbeef0bad };
181 
182 
183    base = (unsigned long) &arrI;
184    offset = ((unsigned long) &arrI[1]) - base;
185    __asm__ volatile ("ori 20, %0, 0"::"r" (base));
186    __asm__ volatile ("ori 21, %0, 0"::"r" (offset));
187    __asm__ volatile ("lwarx %0, 20, 21, 1":"=r" (RT));
188    printf("lwarx => 0x%llx\n", RT);
189 
190 #ifdef __powerpc64__
191    base = (unsigned long) &arrL;
192    offset = ((unsigned long) &arrL[1]) - base;
193    __asm__ volatile ("ori 20, %0, 0"::"r" (base));
194    __asm__ volatile ("ori 21, %0, 0"::"r" (offset));
195    __asm__ volatile ("ldarx %0, 20, 21, 1":"=r" (RT));
196    printf("ldarx => 0x%llx\n", RT);
197 #endif
198 
199 }
200 
main(void)201 int main(void)
202 {
203    (void) test_reservation();
204    test_fcpsgn();
205    (void) test_double_pair_instrs();
206    test_lfiwax();
207    test_parity_instrs();
208    return 0;
209 }
210