Home | History | Annotate | Download | only in s390x
      1 #include <float.h>
      2 #include <stdio.h>
      3 #include <assert.h>
      4 #include "opcodes.h"
      5 
      6 
      7 #define L2F(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 F2L(insn, initial, type, round, cc)                              \
     16 ({                                                                       \
     17    register type source asm("f0") =  initial;                            \
     18    register unsigned long 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_INSN_L2F32(insn, round)                                       \
     28 ({                                                                       \
     29    float f32;                                                            \
     30    printf(#insn " %f\n", L2F(insn, 0, f32, round));                      \
     31    printf(#insn " %f\n", L2F(insn, 1, f32, round));                      \
     32    printf(#insn " %f\n", L2F(insn, 0xffffffffUL, f32, round));           \
     33    printf(#insn " %f\n", L2F(insn, 0x80000000UL, f32, round));           \
     34    printf(#insn " %f\n", L2F(insn, 0x7fffffffUL, f32, round));           \
     35    printf(#insn " %f\n", L2F(insn, 0x100000000UL, f32, round));          \
     36    printf(#insn " %f\n", L2F(insn, 0xffffffffffffffffUL, f32, round));   \
     37    printf(#insn " %f\n", L2F(insn, 0x8000000000000000UL, f32, round));   \
     38    printf(#insn " %f\n", L2F(insn, 0x7fffffffffffffffUL, f32, round));   \
     39 })
     40 
     41 #define DO_INSN_L2F64(insn, round)                                       \
     42 ({                                                                       \
     43    double f64;                                                           \
     44    printf(#insn " %f\n", L2F(insn, 0, f64, round));                      \
     45    printf(#insn " %f\n", L2F(insn, 1, f64, round));                      \
     46    printf(#insn " %f\n", L2F(insn, 0xffffffffUL, f64, round));           \
     47    printf(#insn " %f\n", L2F(insn, 0x80000000UL, f64, round));           \
     48    printf(#insn " %f\n", L2F(insn, 0x7fffffffUL, f64, round));           \
     49    printf(#insn " %f\n", L2F(insn, 0x100000000UL, f64, round));          \
     50    printf(#insn " %f\n", L2F(insn, 0xffffffffffffffffUL, f64, round));   \
     51    printf(#insn " %f\n", L2F(insn, 0x8000000000000000UL, f64, round));   \
     52    printf(#insn " %f\n", L2F(insn, 0x7fffffffffffffffUL, f64, round));   \
     53 })
     54 
     55 #define DO_INSN_L2F128(insn, round)                                      \
     56 ({                                                                       \
     57    long double f128;                                                     \
     58    printf(#insn " %Lf\n", L2F(insn, 0, f128, round));                    \
     59    printf(#insn " %Lf\n", L2F(insn, 1, f128, round));                    \
     60    printf(#insn " %Lf\n", L2F(insn, 0xffffffffUL, f128, round));         \
     61    printf(#insn " %Lf\n", L2F(insn, 0x80000000UL, f128, round));         \
     62    printf(#insn " %Lf\n", L2F(insn, 0x7fffffffUL, f128, round));         \
     63    printf(#insn " %Lf\n", L2F(insn, 0x100000000UL, f128, round));        \
     64    printf(#insn " %Lf\n", L2F(insn, 0xffffffffffffffffUL, f128, round)); \
     65    printf(#insn " %Lf\n", L2F(insn, 0x8000000000000000UL, f128, round)); \
     66    printf(#insn " %Lf\n", L2F(insn, 0x7fffffffffffffffUL, f128, round)); \
     67 })
     68 
     69 #define DO_INSN_F2L(insn, round, type)                                   \
     70 ({                                                                       \
     71    int cc;                                                               \
     72    printf(#insn " %lu ", F2L(insn, -1.1, type, round, cc));              \
     73    printf("cc=%d\n", cc);                                                \
     74    printf(#insn " %lu ", F2L(insn, 0, type, round, cc));                 \
     75    printf("cc=%d\n", cc);                                                \
     76    printf(#insn " %lu ", F2L(insn, 1, type, round, cc));                 \
     77    printf("cc=%d\n", cc);                                                \
     78    printf(#insn " %lu ", F2L(insn, 1.4, type, round, cc));               \
     79    printf("cc=%d\n", cc);                                                \
     80    printf(#insn " %lu ", F2L(insn, 1.5, type, round, cc));               \
     81    printf("cc=%d\n", cc);                                                \
     82    printf(#insn " %lu ", F2L(insn, 1.6, type, round, cc));               \
     83    printf("cc=%d\n", cc);                                                \
     84    printf(#insn " %lu ", F2L(insn, 1.6E+4, type, round, cc));            \
     85    printf("cc=%d\n", cc);                                                \
     86    printf(#insn " %lu ", F2L(insn, 1.6E+8, type, round, cc));            \
     87    printf("cc=%d\n", cc);                                                \
     88    printf(#insn " %lu ", F2L(insn, 1.6E+12, type, round, cc));           \
     89    printf("cc=%d\n", cc);                                                \
     90    printf(#insn " %lu ", F2L(insn, 1.6E+20, type, round, cc));           \
     91    printf("cc=%d\n", cc);                                                \
     92    printf(#insn " %lu ", F2L(insn, 1.6E+200, type, round, cc));          \
     93    printf("cc=%d\n", cc);                                                \
     94    printf(#insn " %lu ", F2L(insn, 1.6E+2000L, type, round, cc));        \
     95    printf("cc=%d\n", cc);                                                \
     96    printf(#insn " %lu ", F2L(insn, 1.6E-4, type, round, cc));            \
     97    printf("cc=%d\n", cc);                                                \
     98    printf(#insn " %lu ", F2L(insn, FLT_MIN, type, round, cc));           \
     99    printf("cc=%d\n", cc);                                                \
    100    printf(#insn " %lu ", F2L(insn, FLT_MAX, type, round, cc));           \
    101    printf("cc=%d\n", cc);                                                \
    102    printf(#insn " %lu ", F2L(insn, DBL_MIN, type, round, cc));           \
    103    printf("cc=%d\n", cc);                                                \
    104    printf(#insn " %lu ", F2L(insn, DBL_MAX, type, round, cc));           \
    105    printf("cc=%d\n", cc);                                                \
    106    printf(#insn " %lu ", F2L(insn, LDBL_MIN, type, round, cc));          \
    107    printf("cc=%d\n", cc);                                                \
    108    printf(#insn " %lu ", F2L(insn, LDBL_MAX, type, round, cc));          \
    109    printf("cc=%d\n", cc);                                                \
    110 })
    111 
    112 #define DO_L2F(round)                                                    \
    113 ({                                                                       \
    114    DO_INSN_L2F32(CELFBR, round);                                         \
    115    DO_INSN_L2F32(CELGBR, round);                                         \
    116    DO_INSN_L2F64(CDLFBR, round);                                         \
    117    DO_INSN_L2F64(CDLGBR, round);                                         \
    118    DO_INSN_L2F128(CXLFBR, round);                                        \
    119    DO_INSN_L2F128(CXLGBR, round);                                        \
    120 })
    121 
    122 #define DO_F2L(round)                                                    \
    123 ({                                                                       \
    124    DO_INSN_F2L(CLFEBR, round, float);                                    \
    125    DO_INSN_F2L(CLGEBR, round, float);                                    \
    126    DO_INSN_F2L(CLFDBR, round, double);                                   \
    127    DO_INSN_F2L(CLGDBR, round, double);                                   \
    128    DO_INSN_F2L(CLFXBR, round, long double);                              \
    129    DO_INSN_F2L(CLGXBR, round, long double);                              \
    130 })
    131 
    132 
    133 int main()
    134 {
    135    assert(sizeof(long double) == 16);
    136    DO_L2F(4);
    137    DO_F2L(4);
    138 
    139    DO_L2F(5);
    140    DO_F2L(5);
    141 
    142    DO_L2F(6);
    143    DO_F2L(6);
    144 
    145    DO_L2F(7);
    146    DO_F2L(7);
    147 
    148    return 0;
    149 }
    150