Home | History | Annotate | Download | only in s390x
      1 #include <stdio.h>
      2 #include "opcodes.h"
      3 #include "dfp_utils.h"
      4 #define __STDC_WANT_DEC_FP__ 1
      5 #include <float.h>
      6 
      7 #define I2D(insn,  initial, target,round)                               \
      8   ({                                                                    \
      9     register int source asm("2") =  initial;                            \
     10     register typeof(target) _t asm("f0");                               \
     11     asm volatile(insn(round,0,0,2) :"=f" (_t):"d"(source));             \
     12     _t;                                                                 \
     13 })
     14 
     15 #define D2I(insn, initial, type, round, cc)                             \
     16   ({                                                                    \
     17     register type source asm("f0") =  initial;                          \
     18     register int target asm ("2") = 0;                                  \
     19     asm volatile(insn(round,0,2,0)                                      \
     20                  "ipm %1\n\t"                                           \
     21                  "srl %1,28\n\t"                                        \
     22                  :"=d" (target), "=d" (cc) :"f"(source):"cc");          \
     23     target;                                                             \
     24 })
     25 
     26 
     27 #define DO_PRINT_I2D(insn, l, d, round)                                 \
     28   ({                                                                    \
     29     printf(#insn " round=%d %d -> ", 0x##round, l);                     \
     30     d = I2D(insn, l, d, round);                                         \
     31     DFP_VAL_PRINT(d, typeof(d));                                        \
     32     printf("\n");                                                       \
     33   })
     34 
     35 #define DO_INSN_I2D(insn, round, type)                                  \
     36   ({                                                                    \
     37     type d;                                                             \
     38     DO_PRINT_I2D(insn, 0, d, round);                                    \
     39     DO_PRINT_I2D(insn, 1, d, round);                                    \
     40     DO_PRINT_I2D(insn, 0xffffffff, d, round);                           \
     41     DO_PRINT_I2D(insn, 0x80000000, d, round);                           \
     42     DO_PRINT_I2D(insn, 0x7fffffff, d, round);                           \
     43    })
     44 
     45 #define DO_PRINT_D2I(insn, d, type, round, cc)                          \
     46   ({                                                                    \
     47     printf(#insn " round=%d ", 0x##round);                              \
     48     DFP_VAL_PRINT(d, type);                                             \
     49     printf(" -> %d ", D2I(insn, d, type, round, cc));                   \
     50     printf("cc=%d\n", cc);                                              \
     51   })
     52 
     53 #define DO_INSN_D2I(insn, round, type)                                  \
     54   ({                                                                    \
     55     int cc;                                                             \
     56     type d;                                                             \
     57     d = -1.1DD;                                                         \
     58     DO_PRINT_D2I(insn, d, type, round, cc);                             \
     59     d = 0.DD;                                                           \
     60     DO_PRINT_D2I(insn, d, type, round, cc);                             \
     61     d = 1.DD;                                                           \
     62     DO_PRINT_D2I(insn, d, type, round, cc);                             \
     63     d = 1.4DD;                                                          \
     64     DO_PRINT_D2I(insn, d, type, round, cc);                             \
     65     d = 1.5DD;                                                          \
     66     DO_PRINT_D2I(insn, d, type, round, cc);                             \
     67     d = 1.6DD;                                                          \
     68     DO_PRINT_D2I(insn, d, type, round, cc);                             \
     69     d = 1.6E+4DD;                                                       \
     70     DO_PRINT_D2I(insn, d, type, round, cc);                             \
     71     d = 1.6E+8DD;                                                       \
     72     DO_PRINT_D2I(insn, d, type, round, cc);                             \
     73     d = 1.6E+4DD;                                                       \
     74     DO_PRINT_D2I(insn, d, type, round, cc);                             \
     75     d = 1.6E+12DD;                                                      \
     76     DO_PRINT_D2I(insn, d, type, round, cc);                             \
     77     d = 1.6E+20DD;                                                      \
     78     DO_PRINT_D2I(insn, d, type, round, cc);                             \
     79     d = 1.6E+200DD;                                                     \
     80     DO_PRINT_D2I(insn, d, type, round, cc);                             \
     81     d = 1.6E-4DD;                                                       \
     82     DO_PRINT_D2I(insn, d, type, round, cc);                             \
     83     d = DEC32_MIN;                                                      \
     84     DO_PRINT_D2I(insn, d, type, round, cc);                             \
     85     d = DEC32_MAX;                                                      \
     86     DO_PRINT_D2I(insn, d, type, round, cc);                             \
     87     d = DEC64_MIN;                                                      \
     88     DO_PRINT_D2I(insn, d, type, round, cc);                             \
     89     d = DEC64_MAX;                                                      \
     90     DO_PRINT_D2I(insn, d, type, round, cc);                             \
     91   })
     92 
     93 #define DO_D2I(round)                                                   \
     94   ({                                                                    \
     95     DO_INSN_D2I(CGDTRA,  round, _Decimal64);                            \
     96     DO_INSN_D2I(CGXTRA,  round, _Decimal128);                           \
     97   })
     98 
     99 
    100 int main()
    101 {
    102   /* rounding mode is not used for the I64 -> D128 conversion */
    103   DO_INSN_I2D(CXGTRA, 0, _Decimal128);
    104 
    105   /* Omit rounding mode value 0 and 2 as the current DFP rounding
    106      mode is chosen for these values. */
    107   DO_INSN_I2D(CDGTRA, 1, _Decimal64);
    108   DO_D2I(1);
    109 
    110   DO_INSN_I2D(CDGTRA, 3, _Decimal64);
    111   DO_D2I(3);
    112 
    113   DO_INSN_I2D(CDGTRA, 4, _Decimal64);
    114   DO_D2I(4);
    115 
    116   DO_INSN_I2D(CDGTRA, 5, _Decimal64);
    117   DO_D2I(5);
    118 
    119   DO_INSN_I2D(CDGTRA, 6, _Decimal64);
    120   DO_D2I(6);
    121 
    122   DO_INSN_I2D(CDGTRA, 7, _Decimal64);
    123   DO_D2I(7);
    124 
    125   DO_INSN_I2D(CDGTRA, 8, _Decimal64);
    126   DO_D2I(8);
    127 
    128   DO_INSN_I2D(CDGTRA, 9, _Decimal64);
    129   DO_D2I(9);
    130 
    131   DO_INSN_I2D(CDGTRA, a, _Decimal64);
    132   DO_D2I(a);
    133 
    134   DO_INSN_I2D(CDGTRA, b, _Decimal64);
    135   DO_D2I(b);
    136 
    137   DO_INSN_I2D(CDGTRA, c, _Decimal64);
    138   DO_D2I(c);
    139 
    140   DO_INSN_I2D(CDGTRA, d, _Decimal64);
    141   DO_D2I(d);
    142 
    143   DO_INSN_I2D(CDGTRA, e, _Decimal64);
    144   DO_D2I(e);
    145 
    146   DO_INSN_I2D(CDGTRA, f, _Decimal64);
    147   DO_D2I(f);
    148 
    149   return 0;
    150 }
    151