Home | History | Annotate | Download | only in s390x
      1 #include <stdio.h>
      2 #include "opcodes.h"
      3 
      4 /* The FLOGR insn reads from register R2 and writes to register R1 and
      5    R1 + 1. So we need to distinguish three cases:
      6 
      7    (1) All three registers R1, R1 + 1, and R2 are distinct
      8    (2) R2 == R1
      9    (3) R2 == R1 + 1
     10 
     11    These are tested by flogr1, flogr2, and flogr3, respectively. */
     12 
     13 /* Call FLOGR on INPUT. The results are returned through the parms. */
     14 
     15 /* R2 != R1 && R2 != R1 + 1 */
     16 void
     17 flogr1(unsigned long input, unsigned long *bitpos, unsigned long *modval,
     18        unsigned int *cc)
     19 {
     20    unsigned int psw;
     21    register unsigned long value asm("4") = input;
     22 
     23    asm volatile ( FLOGR(2,4)
     24                   "ipm   %[psw]\n\t"
     25                   "stg   2, %[bitpos]\n\t"
     26                   "stg   3, %[modval]\n\t"
     27                   : [bitpos]"=m"(*bitpos), [modval]"=m"(*modval),
     28                     [psw]"=&d"(psw)
     29                   : [val] "d"(value)
     30                   : "2", "3", "cc");
     31 
     32    *cc = psw >> 28;
     33 #if 0
     34    printf("value = %lx,  bitpos = %lu,  modval = %lx,  cc = %d\n",
     35           value, *bitpos, *modval, *cc);
     36 #endif
     37 }
     38 
     39 /* R2 == R1 */
     40 void
     41 flogr2(unsigned long input, unsigned long *bitpos, unsigned long *modval,
     42        unsigned int *cc)
     43 {
     44    unsigned int psw;
     45    register unsigned long value asm("2") = input;
     46 
     47    asm volatile ( FLOGR(2,2)
     48                   "ipm   %[psw]\n\t"
     49                   "stg   2, %[bitpos]\n\t"
     50                   "stg   3, %[modval]\n\t"
     51                   : [bitpos]"=m"(*bitpos), [modval]"=m"(*modval),
     52                     [psw]"=&d"(psw), [val] "+d"(value)
     53                   :
     54                   : "3", "cc");
     55 
     56    *cc = psw >> 28;
     57 #if 0
     58    printf("value = %lx,  bitpos = %lu,  modval = %lx,  cc = %d\n",
     59           value, *bitpos, *modval, *cc);
     60 #endif
     61 }
     62 
     63 /* R2 == R1 + 1 */
     64 void
     65 flogr3(unsigned long input, unsigned long *bitpos, unsigned long *modval,
     66        unsigned int *cc)
     67 {
     68    unsigned int psw;
     69    register unsigned long value asm("3") = input;
     70 
     71    asm volatile ( FLOGR(2,3)
     72                   "ipm   %[psw]\n\t"
     73                   "stg   2, %[bitpos]\n\t"
     74                   "stg   3, %[modval]\n\t"
     75                   : [bitpos]"=m"(*bitpos), [modval]"=m"(*modval),
     76                     [psw]"=&d"(psw), [val] "+d"(value)
     77                   :
     78                   : "2", "cc");
     79 
     80    *cc = psw >> 28;
     81 #if 0
     82    printf("value = %lx,  bitpos = %lu,  modval = %lx,  cc = %d\n",
     83           value, *bitpos, *modval, *cc);
     84 #endif
     85 }
     86 
     87 void
     88 runtest(void (*func)(unsigned long, unsigned long *, unsigned long *,
     89                      unsigned int *))
     90 {
     91    unsigned long bitpos, modval, value;
     92    unsigned int cc;
     93    int i;
     94 
     95    /* Value 0 is special */
     96    value = 0;
     97    func(value, &bitpos, &modval, &cc);
     98    if (modval != 0)  fprintf(stderr, "modval is wrong for %lx\n", value);
     99    if (bitpos != 64) fprintf(stderr, "bitpos is wrong for %lx\n", value);
    100    if (cc != 0)      fprintf(stderr, "cc is wrong for %lx\n", value);
    101 
    102    /* Test with exactly 1 bit set */
    103    for (i = 0; i < 64; ++i) {
    104      value = 1ull << i;
    105      func(value, &bitpos, &modval, &cc);
    106      if (modval != 0) fprintf(stderr, "modval is wrong for %lx\n", value);
    107      if (bitpos != 63 - i) fprintf(stderr, "bitpos is wrong for %lx\n", value);
    108      if (cc != 2)          fprintf(stderr, "cc is wrong for %lx\n", value);
    109    }
    110 
    111    /* Test with all bits 1 right from first 1 bit */
    112    for (i = 1; i < 64; ++i) {
    113      value = 1ull << i;
    114      value = value | (value - 1);
    115      func(value, &bitpos, &modval, &cc);
    116      if (modval != (value >> 1)) fprintf(stderr, "modval is wrong for %lx\n", value);
    117      if (bitpos != 63 - i) fprintf(stderr, "bitpos is wrong for %lx\n", value);
    118      if (cc != 2)          fprintf(stderr, "cc is wrong for %lx\n", value);
    119    }
    120 }
    121 
    122 
    123 int main()
    124 {
    125    runtest(flogr1);
    126    runtest(flogr2);
    127    runtest(flogr3);
    128 
    129    return 0;
    130 }
    131