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 L2D(insn,  initial, target,round)                               \
      8   ({                                                                    \
      9     register unsigned long 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 I2D(insn,  initial, target,round)                               \
     16   ({                                                                    \
     17     register int source asm("2") =  initial;                            \
     18     register typeof(target) _t asm("f0");                               \
     19     asm volatile(insn(round,0,0,2) :"=f" (_t):"d"(source));             \
     20     _t;                                                                 \
     21 })
     22 
     23 #define D2L(insn, initial, type, round, cc)                             \
     24   ({                                                                    \
     25     register type source asm("f0") =  initial;                          \
     26     register unsigned long target asm ("2") = 0;                        \
     27     asm volatile(insn(round,0,2,0)                                      \
     28                  "ipm %1\n\t"                                           \
     29                  "srl %1,28\n\t"                                        \
     30                  :"=d" (target), "=d" (cc) :"f"(source):"cc");          \
     31     target;                                                             \
     32   })
     33 
     34 #define D2I(insn, initial, type, round, cc)                             \
     35   ({                                                                    \
     36     register type source asm("f0") =  initial;                          \
     37     register int target asm ("2") = 0;                                  \
     38     asm volatile(insn(round,0,2,0)                                      \
     39                  "ipm %1\n\t"                                           \
     40                  "srl %1,28\n\t"                                        \
     41                  :"=d" (target), "=d" (cc) :"f"(source):"cc");          \
     42     target;                                                             \
     43 })
     44 
     45 
     46 #define DO_PRINT_L2D(insn, l, d, round)                                 \
     47   ({                                                                    \
     48     printf(#insn " round=%d %lu -> ", 0x##round, l);                    \
     49     d = L2D(insn, l, d, round);                                         \
     50     DFP_VAL_PRINT(d, typeof(d));                                        \
     51     printf("\n");                                                       \
     52   })
     53 
     54 #define DO_INSN_L2D(insn, round, type)                                  \
     55   ({                                                                    \
     56     type d;                                                             \
     57     DO_PRINT_L2D(insn, 0UL, d, round);                                  \
     58     DO_PRINT_L2D(insn, 1UL, d, round);                                  \
     59     DO_PRINT_L2D(insn, 0xffffffffUL, d, round);                         \
     60     DO_PRINT_L2D(insn, 0x80000000UL, d, round);                         \
     61     DO_PRINT_L2D(insn, 0x7fffffffUL, d, round);                         \
     62     DO_PRINT_L2D(insn, 0x100000000UL, d, round);                        \
     63     DO_PRINT_L2D(insn, 0xffffffffffffffffUL, d, round);                 \
     64     DO_PRINT_L2D(insn, 0x8000000000000000UL, d, round);                 \
     65     DO_PRINT_L2D(insn, 0x7fffffffffffffffUL, d, round);                 \
     66   })
     67 
     68 #define DO_PRINT_I2D(insn, l, d, round)                                 \
     69   ({                                                                    \
     70     printf(#insn " round=%d %d -> ", 0x##round, l);                     \
     71     d = I2D(insn, l, d, round);                                         \
     72     DFP_VAL_PRINT(d, typeof(d));                                        \
     73     printf("\n");                                                       \
     74   })
     75 
     76 #define DO_INSN_I2D(insn, round, type)                                  \
     77   ({                                                                    \
     78     type d;                                                             \
     79     DO_PRINT_I2D(insn, 0, d, round);                                    \
     80     DO_PRINT_I2D(insn, 1, d, round);                                    \
     81     DO_PRINT_I2D(insn, 0xffffffff, d, round);                           \
     82     DO_PRINT_I2D(insn, 0x80000000, d, round);                           \
     83     DO_PRINT_I2D(insn, 0x7fffffff, d, round);                           \
     84    })
     85 
     86 #define DO_PRINT_D2L(insn, d, type, round, cc)                          \
     87   ({                                                                    \
     88     printf(#insn " round=%d ", 0x##round);                              \
     89     DFP_VAL_PRINT(d, type);                                             \
     90     printf(" -> %lu ", D2L(insn, d, type, round, cc));                  \
     91     printf("cc=%d\n", cc);                                              \
     92   })
     93 
     94 #define DO_INSN_D2L(insn, round, type)                                  \
     95   ({                                                                    \
     96     int cc;                                                             \
     97     type d;                                                             \
     98     d = -1.1DD;                                                         \
     99     DO_PRINT_D2L(insn, d, type, round, cc);                             \
    100     d = 0.DD;                                                           \
    101     DO_PRINT_D2L(insn, d, type, round, cc);                             \
    102     d = 1.DD;                                                           \
    103     DO_PRINT_D2L(insn, d, type, round, cc);                             \
    104     d = 1.4DD;                                                          \
    105     DO_PRINT_D2L(insn, d, type, round, cc);                             \
    106     d = 1.5DD;                                                          \
    107     DO_PRINT_D2L(insn, d, type, round, cc);                             \
    108     d = 1.6DD;                                                          \
    109     DO_PRINT_D2L(insn, d, type, round, cc);                             \
    110     d = 1.6E+4DD;                                                       \
    111     DO_PRINT_D2L(insn, d, type, round, cc);                             \
    112     d = 1.6E+8DD;                                                       \
    113     DO_PRINT_D2L(insn, d, type, round, cc);                             \
    114     d = 1.6E+4DD;                                                       \
    115     DO_PRINT_D2L(insn, d, type, round, cc);                             \
    116     d = 1.6E+12DD;                                                      \
    117     DO_PRINT_D2L(insn, d, type, round, cc);                             \
    118     d = 1.6E+20DD;                                                      \
    119     DO_PRINT_D2L(insn, d, type, round, cc);                             \
    120     d = 1.6E+200DD;                                                     \
    121     DO_PRINT_D2L(insn, d, type, round, cc);                             \
    122     d = 1.6E-4DD;                                                       \
    123     DO_PRINT_D2L(insn, d, type, round, cc);                             \
    124     d = DEC32_MIN;                                                      \
    125     DO_PRINT_D2L(insn, d, type, round, cc);                             \
    126     d = DEC32_MAX;                                                      \
    127     DO_PRINT_D2L(insn, d, type, round, cc);                             \
    128     d = DEC64_MIN;                                                      \
    129     DO_PRINT_D2L(insn, d, type, round, cc);                             \
    130     d = DEC64_MAX;                                                      \
    131     DO_PRINT_D2L(insn, d, type, round, cc);                             \
    132   })
    133 
    134 #define DO_PRINT_D2I(insn, d, type, round, cc)                          \
    135   ({                                                                    \
    136     printf(#insn " round=%d ", 0x##round);                              \
    137     DFP_VAL_PRINT(d, type);                                             \
    138     printf(" -> %d ", D2I(insn, d, type, round, cc));                   \
    139     printf("cc=%d\n", cc);                                              \
    140   })
    141 
    142 #define DO_INSN_D2I(insn, round, type)                                  \
    143   ({                                                                    \
    144     int cc;                                                             \
    145     type d;                                                             \
    146     d = -1.1DD;                                                         \
    147     DO_PRINT_D2I(insn, d, type, round, cc);                             \
    148     d = 0.DD;                                                           \
    149     DO_PRINT_D2I(insn, d, type, round, cc);                             \
    150     d = 1.DD;                                                           \
    151     DO_PRINT_D2I(insn, d, type, round, cc);                             \
    152     d = 1.4DD;                                                          \
    153     DO_PRINT_D2I(insn, d, type, round, cc);                             \
    154     d = 1.5DD;                                                          \
    155     DO_PRINT_D2I(insn, d, type, round, cc);                             \
    156     d = 1.6DD;                                                          \
    157     DO_PRINT_D2I(insn, d, type, round, cc);                             \
    158     d = 1.6E+4DD;                                                       \
    159     DO_PRINT_D2I(insn, d, type, round, cc);                             \
    160     d = 1.6E+8DD;                                                       \
    161     DO_PRINT_D2I(insn, d, type, round, cc);                             \
    162     d = 1.6E+4DD;                                                       \
    163     DO_PRINT_D2I(insn, d, type, round, cc);                             \
    164     d = 1.6E+12DD;                                                      \
    165     DO_PRINT_D2I(insn, d, type, round, cc);                             \
    166     d = 1.6E+20DD;                                                      \
    167     DO_PRINT_D2I(insn, d, type, round, cc);                             \
    168     d = 1.6E+200DD;                                                     \
    169     DO_PRINT_D2I(insn, d, type, round, cc);                             \
    170     d = 1.6E-4DD;                                                       \
    171     DO_PRINT_D2I(insn, d, type, round, cc);                             \
    172     d = DEC32_MIN;                                                      \
    173     DO_PRINT_D2I(insn, d, type, round, cc);                             \
    174     d = DEC32_MAX;                                                      \
    175     DO_PRINT_D2I(insn, d, type, round, cc);                             \
    176     d = DEC64_MIN;                                                      \
    177     DO_PRINT_D2I(insn, d, type, round, cc);                             \
    178     d = DEC64_MAX;                                                      \
    179     DO_PRINT_D2I(insn, d, type, round, cc);                             \
    180   })
    181 
    182 #define DO_D2L(round)                                                   \
    183   ({                                                                    \
    184     DO_INSN_D2L(CLFDTR, round, _Decimal64);                             \
    185     DO_INSN_D2L(CLGDTR, round, _Decimal64);                             \
    186     DO_INSN_D2I(CFDTR,  round, _Decimal64);                             \
    187     DO_INSN_D2L(CLFXTR, round, _Decimal128);                            \
    188     DO_INSN_D2L(CLGXTR, round, _Decimal128);                            \
    189     DO_INSN_D2I(CFXTR,  round, _Decimal128);                            \
    190   })
    191 
    192 
    193 int main()
    194 {
    195   /* rounding mode is not used for the following insns */
    196   DO_INSN_I2D(CDFTR,  0, _Decimal64);
    197   DO_INSN_I2D(CXFTR,  0, _Decimal128);
    198   DO_INSN_L2D(CDLFTR, 0, _Decimal64);
    199   DO_INSN_L2D(CXLFTR, 0, _Decimal128);
    200   DO_INSN_L2D(CXLGTR, 0, _Decimal128);
    201 
    202   /* Omit rounding mode value 0 and 2 as the current DFP rounding
    203      mode is chosen for these values. */
    204   DO_INSN_L2D(CDLGTR, 1, _Decimal64);
    205   DO_D2L(1);
    206 
    207   DO_INSN_L2D(CDLGTR, 3, _Decimal64);
    208   DO_D2L(3);
    209 
    210   DO_INSN_L2D(CDLGTR, 4, _Decimal64);
    211   DO_D2L(4);
    212 
    213   DO_INSN_L2D(CDLGTR, 5, _Decimal64);
    214   DO_D2L(5);
    215 
    216   DO_INSN_L2D(CDLGTR, 6, _Decimal64);
    217   DO_D2L(6);
    218 
    219   DO_INSN_L2D(CDLGTR, 7, _Decimal64);
    220   DO_D2L(7);
    221 
    222   DO_INSN_L2D(CDLGTR, 8, _Decimal64);
    223   DO_D2L(8);
    224 
    225   DO_INSN_L2D(CDLGTR, 9, _Decimal64);
    226   DO_D2L(9);
    227 
    228   DO_INSN_L2D(CDLGTR, a, _Decimal64);
    229   DO_D2L(a);
    230 
    231   DO_INSN_L2D(CDLGTR, b, _Decimal64);
    232   DO_D2L(b);
    233 
    234   DO_INSN_L2D(CDLGTR, c, _Decimal64);
    235   DO_D2L(c);
    236 
    237   DO_INSN_L2D(CDLGTR, d, _Decimal64);
    238   DO_D2L(d);
    239 
    240   DO_INSN_L2D(CDLGTR, e, _Decimal64);
    241   DO_D2L(e);
    242 
    243   DO_INSN_L2D(CDLGTR, f, _Decimal64);
    244   DO_D2L(f);
    245 
    246   return 0;
    247 }
    248