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