Home | History | Annotate | Download | only in s390x
      1 /* basic float <-> signed int conversions available since z900 */
      2 #include <float.h>
      3 #include <stdio.h>
      4 #include "opcodes.h"
      5 
      6 #define I2F(insn,  initial, target,round)                                \
      7 ({                                                                       \
      8    register unsigned long source asm("2") =  initial;                    \
      9    register typeof(target) _t asm("f0");                                 \
     10    asm volatile(insn " 0,2\n\t" :"=f" (_t):"d"(source));                 \
     11    _t;                                                                   \
     12 })
     13 
     14 #define F2L(insn, initial, type, round, cc)                              \
     15 ({                                                                       \
     16    register type source asm("f0") =  initial;                            \
     17    register unsigned long target asm ("2") = 0;                          \
     18    asm volatile(insn " 2," #round ",0\n\t"                               \
     19                 "ipm %1\n\t"                                             \
     20                 "srl %1,28\n\t"                                          \
     21  		:"=d" (target), "=d" (cc) :"f"(source):"cc");            \
     22    target;                                                               \
     23 })
     24 
     25 
     26 #define DO_INSN_I2F32(insn, round)                                       \
     27 ({                                                                       \
     28    float f32;                                                            \
     29    printf(#insn " %f\n", I2F(insn, 0, f32, round));                      \
     30    printf(#insn " %f\n", I2F(insn, 1, f32, round));                      \
     31    printf(#insn " %f\n", I2F(insn, 0xffffffffUL, f32, round));           \
     32    printf(#insn " %f\n", I2F(insn, 0x80000000UL, f32, round));           \
     33    printf(#insn " %f\n", I2F(insn, 0x7fffffffUL, f32, round));           \
     34    printf(#insn " %f\n", I2F(insn, 0x100000000UL, f32, round));          \
     35    printf(#insn " %f\n", I2F(insn, 0xffffffffffffffffUL, f32, round));   \
     36    printf(#insn " %f\n", I2F(insn, 0x8000000000000000UL, f32, round));   \
     37    printf(#insn " %f\n", I2F(insn, 0x7fffffffffffffffUL, f32, round));   \
     38 })
     39 
     40 #define DO_INSN_I2F64(insn, round)                                       \
     41 ({                                                                       \
     42    double f64;                                                           \
     43    printf(#insn " %f\n", I2F(insn, 0, f64, round));                      \
     44    printf(#insn " %f\n", I2F(insn, 1, f64, round));                      \
     45    printf(#insn " %f\n", I2F(insn, 0xffffffffUL, f64, round));           \
     46    printf(#insn " %f\n", I2F(insn, 0x80000000UL, f64, round));           \
     47    printf(#insn " %f\n", I2F(insn, 0x7fffffffUL, f64, round));           \
     48    printf(#insn " %f\n", I2F(insn, 0x100000000UL, f64, round));          \
     49    printf(#insn " %f\n", I2F(insn, 0xffffffffffffffffUL, f64, round));   \
     50    printf(#insn " %f\n", I2F(insn, 0x8000000000000000UL, f64, round));   \
     51    printf(#insn " %f\n", I2F(insn, 0x7fffffffffffffffUL, f64, round));   \
     52 })
     53 
     54 #define DO_INSN_I2F128(insn, round)                                      \
     55 ({                                                                       \
     56    long double f128;                                                     \
     57    printf(#insn " %Lf\n", I2F(insn, 0, f128, round));                    \
     58    printf(#insn " %Lf\n", I2F(insn, 1, f128, round));                    \
     59    printf(#insn " %Lf\n", I2F(insn, 0xffffffffUL, f128, round));         \
     60    printf(#insn " %Lf\n", I2F(insn, 0x80000000UL, f128, round));         \
     61    printf(#insn " %Lf\n", I2F(insn, 0x7fffffffUL, f128, round));         \
     62    printf(#insn " %Lf\n", I2F(insn, 0x100000000UL, f128, round));        \
     63    printf(#insn " %Lf\n", I2F(insn, 0xffffffffffffffffUL, f128, round)); \
     64    printf(#insn " %Lf\n", I2F(insn, 0x8000000000000000UL, f128, round)); \
     65    printf(#insn " %Lf\n", I2F(insn, 0x7fffffffffffffffUL, f128, round)); \
     66 })
     67 
     68 #define DO_INSN_F2L(insn, round, type)                                   \
     69 ({                                                                       \
     70    int cc;                                                               \
     71    printf(#insn " %ld ", F2L(insn, -1.1, type, round, cc));              \
     72    printf("cc=%d\n", cc);                                                \
     73    printf(#insn " %ld ", F2L(insn, 0, type, round, cc));                 \
     74    printf("cc=%d\n", cc);                                                \
     75    printf(#insn " %ld ", F2L(insn, 1, type, round, cc));                 \
     76    printf("cc=%d\n", cc);                                                \
     77    printf(#insn " %ld ", F2L(insn, 1.4, type, round, cc));               \
     78    printf("cc=%d\n", cc);                                                \
     79    printf(#insn " %ld ", F2L(insn, 1.5, type, round, cc));               \
     80    printf("cc=%d\n", cc);                                                \
     81    printf(#insn " %ld ", F2L(insn, 1.6, type, round, cc));               \
     82    printf("cc=%d\n", cc);                                                \
     83    printf(#insn " %ld ", F2L(insn, 1.6E+4, type, round, cc));            \
     84    printf("cc=%d\n", cc);                                                \
     85    printf(#insn " %ld ", F2L(insn, 1.6E+8, type, round, cc));            \
     86    printf("cc=%d\n", cc);                                                \
     87    printf(#insn " %ld ", F2L(insn, 1.6E+12, type, round, cc));           \
     88    printf("cc=%d\n", cc);                                                \
     89    printf(#insn " %ld ", F2L(insn, 1.6E+20, type, round, cc));           \
     90    printf("cc=%d\n", cc);                                                \
     91    printf(#insn " %ld ", F2L(insn, 1.6E+200, type, round, cc));          \
     92    printf("cc=%d\n", cc);                                                \
     93    printf(#insn " %ld ", F2L(insn, 1.6E+2000L, type, round, cc));        \
     94    printf("cc=%d\n", cc);                                                \
     95    printf(#insn " %ld ", F2L(insn, 1.6E-4, type, round, cc));            \
     96    printf("cc=%d\n", cc);                                                \
     97    printf(#insn " %ld ", F2L(insn, FLT_MIN, type, round, cc));           \
     98    printf("cc=%d\n", cc);                                                \
     99    printf(#insn " %ld ", F2L(insn, FLT_MAX, type, round, cc));           \
    100    printf("cc=%d\n", cc);                                                \
    101    printf(#insn " %ld ", F2L(insn, DBL_MIN, type, round, cc));           \
    102    printf("cc=%d\n", cc);                                                \
    103    printf(#insn " %ld ", F2L(insn, DBL_MAX, type, round, cc));           \
    104    printf("cc=%d\n", cc);                                                \
    105    printf(#insn " %ld ", F2L(insn, LDBL_MIN, type, round, cc));          \
    106    printf("cc=%d\n", cc);                                                \
    107    printf(#insn " %ld ", F2L(insn, LDBL_MAX, type, round, cc));          \
    108    printf("cc=%d\n", cc);                                                \
    109 })
    110 
    111 #define DO_I2F(round)                                                    \
    112 ({                                                                       \
    113    DO_INSN_I2F32("cefbr", round);                                        \
    114    DO_INSN_I2F32("cegbr", round);                                        \
    115    DO_INSN_I2F64("cdfbr", round);                                        \
    116    DO_INSN_I2F64("cdgbr", round);                                        \
    117    DO_INSN_I2F128("cxfbr", round);                                       \
    118    DO_INSN_I2F128("cxgbr", round);                                       \
    119 })
    120 
    121 #define DO_F2L(round)                                                    \
    122 ({                                                                       \
    123    DO_INSN_F2L("cfebr", round, float);                                   \
    124    DO_INSN_F2L("cgebr", round, float);                                   \
    125    DO_INSN_F2L("cfdbr", round, double);                                  \
    126    DO_INSN_F2L("cgdbr", round, double);                                  \
    127    DO_INSN_F2L("cfxbr", round, long double);                             \
    128    DO_INSN_F2L("cgxbr", round, long double);                             \
    129 })
    130 
    131 
    132 int main()
    133 {
    134    DO_I2F(4);
    135    DO_F2L(4);
    136 
    137    DO_I2F(5);
    138    DO_F2L(5);
    139 
    140    DO_I2F(6);
    141    DO_F2L(6);
    142 
    143    DO_I2F(7);
    144    DO_F2L(7);
    145 
    146    return 0;
    147 }
    148