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 int word; 28 int i, parity; 29 30 for (i = 0; i < 50; i++) { 31 word = base256(i); 32 #ifdef __powerpc64__ 33 unsigned long long_word = word; 34 __asm__ volatile ("prtyd %0, %1":"=r" (parity):"r"(long_word)); 35 printf("prtyd (%x) => parity=%x\n", i, parity); 36 #endif 37 __asm__ volatile ("prtyw %0, %1":"=r" (parity):"r"(word)); 38 printf("prtyw (%x) => parity=%x\n", i, parity); 39 } 40 } 41 42 void test_lfiwax() 43 { 44 unsigned long base; 45 // unsigned long offset; 46 47 typedef struct { 48 unsigned int hi; 49 unsigned int lo; 50 } int_pair_t; 51 52 int_pair_t *ip; 53 foo = -1024.0; 54 base = (unsigned long) &foo; 55 56 __asm__ volatile ("lfiwax %0, 0, %1":"=f" (FRT1):"r"(base)); 57 ip = (int_pair_t *) & FRT1; 58 printf("lfiwax (%f) => FRT=(%x, %x)\n", foo, ip->hi, ip->lo); 59 60 61 } 62 63 64 65 /* lfdp FPp, DS(RA) : load float double pair 66 ** FPp = leftmost 64 bits stored at DS(RA) 67 ** FPp+1= rightmost 64 bits stored at DS(RA) 68 ** FPp must be an even float register 69 ** 70 ** The [st|l]fdp[x] instructions were put into the "Floating-Point.Phased-Out" 71 ** category in ISA 2.06 (i.e., POWER7 timeframe). If valgrind and its 72 ** testsuite are built with -mcpu=power7 (or later), then the assembler will 73 ** not recognize those phased out instructions. 74 */ 75 void test_double_pair_instrs() 76 { 77 #ifdef HAVE_AS_PPC_FPPO 78 typedef struct { 79 double hi; 80 double lo; 81 } dbl_pair_t; 82 83 /* the following decls are for alignment */ 84 int i; 85 dbl_pair_t dbl_pair[3]; /* must be quad word aligned */ 86 unsigned long base; 87 unsigned long offset; 88 89 for (i = 0; i < 3; i++) { 90 dbl_pair[i].hi = -1024.0 + i; 91 dbl_pair[i].lo = 1024.0 + i + 1; 92 } 93 94 __asm__ volatile ("lfdp 10, %0"::"m" (dbl_pair[0])); 95 __asm__ volatile ("fmr %0, 10":"=f" (FRT1)); 96 __asm__ volatile ("fmr %0, 11":"=f" (FRT2)); 97 printf("lfdp (%f, %f) => F_hi=%f, F_lo=%f\n", 98 dbl_pair[0].hi, dbl_pair[0].lo, FRT1, FRT2); 99 100 101 FRT1 = 2.2048; 102 FRT2 = -4.1024; 103 __asm__ volatile ("fmr 10, %0"::"f" (FRT1)); 104 __asm__ volatile ("fmr 11, %0"::"f" (FRT2)); 105 __asm__ volatile ("stfdp 10, %0"::"m" (dbl_pair[1])); 106 printf("stfdp (%f, %f) => F_hi=%f, F_lo=%f\n", 107 FRT1, FRT2, dbl_pair[1].hi, dbl_pair[1].lo); 108 109 FRT1 = 0.0; 110 FRT2 = -1.0; 111 base = (unsigned long) &dbl_pair; 112 offset = (unsigned long) &dbl_pair[1] - base; 113 __asm__ volatile ("ori 20, %0, 0"::"r" (base)); 114 __asm__ volatile ("ori 21, %0, 0"::"r" (offset)); 115 __asm__ volatile ("lfdpx 10, 20, 21"); 116 __asm__ volatile ("fmr %0, 10":"=f" (FRT1)); 117 __asm__ volatile ("fmr %0, 11":"=f" (FRT2)); 118 printf("lfdpx (%f, %f) => F_hi=%f, F_lo=%f\n", 119 dbl_pair[1].hi, dbl_pair[1].lo, FRT1, FRT2); 120 121 FRT1 = 8.2048; 122 FRT2 = -16.1024; 123 base = (unsigned long) &dbl_pair; 124 offset = (unsigned long) &dbl_pair[2] - base; 125 __asm__ volatile ("ori 20, %0, 0"::"r" (base)); 126 __asm__ volatile ("ori 21, %0, 0"::"r" (offset)); 127 __asm__ volatile ("fmr %0, 10":"=f" (FRT1)); 128 __asm__ volatile ("fmr %0, 11":"=f" (FRT2)); 129 __asm__ volatile ("stfdpx 10, 20, 21"); 130 printf("stfdpx (%f, %f) => F_hi=%f, F_lo=%f\n", 131 FRT1, FRT2, dbl_pair[2].hi, dbl_pair[2].lo); 132 #endif 133 } 134 135 136 /* The contents of FRB with bit set 0 set to bit 0 of FRA copied into FRT */ 137 void test_fcpsgn() 138 { 139 double A[] = { 140 10.101010, 141 -0.0, 142 0.0, 143 -10.101010 144 }; 145 146 double B[] = { 147 11.111111, 148 -0.0, 149 0.0, 150 -11.111111 151 }; 152 153 double FRT, FRA, FRB; 154 int i, j; 155 156 for (i = 0; i < 4; i++) { 157 FRA = A[i]; 158 for (j = 0; j < 4; j++) { 159 FRB = B[j]; 160 __asm__ volatile ("fcpsgn %0, %1, %2":"=f" (FRT):"f"(FRA), 161 "f"(FRB)); 162 printf("fcpsgn sign=%f, base=%f => %f\n", FRA, FRB, FRT); 163 } 164 } 165 } 166 167 /* b0 may be non-zero in lwarx/ldarx Power6 instrs */ 168 void test_reservation() 169 { 170 171 int RT; 172 unsigned long base; 173 unsigned long offset; 174 long arr[4] = { 0xdeadbeef, 0xbad0beef, 0xbeefdead, 0xbeef0bad }; 175 176 177 base = (unsigned long) &arr; 178 offset = (unsigned long) &arr[1] - base; 179 __asm__ volatile ("ori 20, %0, 0"::"r" (base)); 180 __asm__ volatile ("ori 21, %0, 0"::"r" (offset)); 181 __asm__ volatile ("lwarx %0, 20, 21, 1":"=r" (RT)); 182 printf("lwarx => %x\n", RT); 183 184 #ifdef __powerpc64__ 185 offset = (unsigned long) &arr[1] - base; 186 __asm__ volatile ("ori 21, %0, 0"::"r" (offset)); 187 __asm__ volatile ("ldarx %0, 20, 21, 1":"=r" (RT)); 188 printf("ldarx => %x\n", RT); 189 #endif 190 191 } 192 193 int main(void) 194 { 195 (void) test_reservation(); 196 test_fcpsgn(); 197 (void) test_double_pair_instrs(); 198 test_lfiwax(); 199 test_parity_instrs(); 200 return 0; 201 } 202