Home | History | Annotate | Download | only in ppc32
      1 #include <stdio.h>
      2 
      3 double foo = -1.0;
      4 double FRT1;
      5 double FRT2;
      6 int 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 
     24 void 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 
     40 void 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 */
     68 void 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 */
    128 void 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 */
    159 void 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 
    184 int 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