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