Home | History | Annotate | Download | only in s390x
      1 #include <stdlib.h>
      2 #include <assert.h>
      3 #include <stdio.h>
      4 #include <stdint.h>
      5 #include <inttypes.h>
      6 
      7 /* This testcase is to illustrate that for convert to fixed the condition
      8    code depends on the rounding mode. */
      9 
     10 const char *
     11 rtext(unsigned round)
     12 {
     13    switch (round) {
     14    case 0: return "[fpc]";
     15    case 1: return "[->near/away]";
     16       /* 2 is invalid */
     17    case 3: return "[prep short]";
     18    case 4: return "[->near/even]";
     19    case 5: return "[->0]";
     20    case 6: return "[->+inf]";
     21    case 7: return "[->-inf]";
     22    }
     23    assert(0);
     24 }
     25 
     26 #define convert_to_int(opcode,src_type,dst_type,dst_fmt,round,value) \
     27 do { \
     28    src_type src = value; \
     29    dst_type dst;         \
     30    unsigned cc;          \
     31                          \
     32    __asm__ volatile (opcode " %[dst]," #round ",%[src]\n\t"     \
     33                      "ipm %[cc]\n\t"                  \
     34                      "srl %[cc],28\n\t"               \
     35                      : [dst] "=d"(dst), [cc] "=d"(cc) \
     36                      : [src] "f"(src)                 \
     37                      : "cc");                         \
     38                                                       \
     39    printf("%s %-20s %f\t-> %"dst_fmt"\tcc = %u\n",    \
     40           opcode, rtext(round), src, dst, cc);        \
     41 } while (0)
     42 
     43 
     44 #define cfdbr(round,value) \
     45         convert_to_int("cfdbr",double,int32_t,PRId32,round,value)
     46 
     47 int main(void)
     48 {
     49    double dval;
     50 
     51    dval = -2147483648.5;  // a < MN
     52 
     53    // f64 -> i32
     54 
     55    cfdbr(4, dval);  // round to nearest with ties to even
     56    cfdbr(5, dval);  // round to zero
     57    cfdbr(6, dval);  // round to +inf
     58 
     59    /* The next invocation needs to give cc=3. It used to give cc=1 when
     60       we were considering the to-be-converted value ONLY */
     61    cfdbr(7, dval);  // round to -inf
     62 
     63    return 0;
     64 }
     65