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