Home | History | Annotate | Download | only in ppc64
      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