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