1 #include <stdio.h> 2 #include <config.h> 3 4 double foo = -1.0; 5 double FRT1; 6 double FRT2; 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 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 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 */ 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 */ 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 */ 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 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