Home | History | Annotate | Download | only in s390x
      1 #include <stdio.h>
      2 #include <stdint.h>
      3 #include "dfp_utils.h"
      4 #define __STDC_WANT_DEC_FP__ 1
      5 #include <float.h>
      6 
      7 #ifndef PFPO_FUNCTIONS
      8 #define PFPO_FUNCTIONS
      9 #define PFPO_F32_TO_D32   0x01080500
     10 #define PFPO_D32_TO_F32   0x01050800
     11 #define PFPO_F32_TO_D64   0x01090500
     12 #define PFPO_D32_TO_F64   0x01060800
     13 #define PFPO_F32_TO_D128  0x010A0500
     14 #define PFPO_D32_TO_F128  0x01070800
     15 #define PFPO_F64_TO_D32   0x01080600
     16 #define PFPO_D64_TO_F32   0x01050900
     17 #define PFPO_F64_TO_D64   0x01090600
     18 #define PFPO_D64_TO_F64   0x01060900
     19 #define PFPO_F64_TO_D128  0x010A0600
     20 #define PFPO_D64_TO_F128  0x01070900
     21 #define PFPO_D128_TO_F64  0x01060A00
     22 #define PFPO_F128_TO_D32  0x01080700
     23 #define PFPO_D128_TO_F32  0x01050A00
     24 #define PFPO_F128_TO_D64  0x01090700
     25 #define PFPO_D128_TO_F64  0x01060A00
     26 #define PFPO_F128_TO_D128 0x010A0700
     27 #define PFPO_D128_TO_F128 0x01070A00
     28 
     29 #define PFPO(initial, src_type, dst_type, fn_code, round, ret_code, cc) \
     30 ({                                                                      \
     31   register src_type src_reg asm("f4") = initial;                        \
     32   register dst_type dst_reg asm("f0");                                  \
     33   register unsigned long fn asm("0") = fn_code | (round & 0xf);         \
     34   register unsigned int ret asm("1");                                   \
     35   asm volatile(".short 0x010a\n\t"                                      \
     36                "ipm %2\n\t"                                             \
     37                "srl %2,28\n\t"                                          \
     38                :"=f"(dst_reg), "=d"(ret), "=d" (cc)                     \
     39                : "f"(src_reg), "d"(fn));                                \
     40   ret_code = ret;                                                       \
     41   dst_reg;                                                              \
     42 })
     43 
     44 #endif /* PFPO_FUNCTIONS */
     45 
     46 /* Test BFP <-> DFP conversions */
     47 int main()
     48 {
     49   int cc;
     50   uint8_t i, j;
     51   unsigned int ret_code;
     52 
     53   float f32;
     54   double f64;
     55   long double f128;
     56 
     57   _Decimal32 d32;
     58   _Decimal64 d64;
     59   _Decimal128 d128;
     60 
     61   float f32_in[] = {123.5656789, FLT_MAX, FLT_MIN};
     62   double f64_in[] = {123456789999.5656789, DBL_MIN, DBL_MAX};
     63   long double f128_in[] = {1234567812345678912345678912.5656789L,
     64                            LDBL_MIN, LDBL_MAX};
     65 
     66   _Decimal32 d32_in[] = {123.5656789DF, DEC32_MAX, DEC32_MIN};
     67   _Decimal64 d64_in[] = {123456789999.5656789DD, DEC64_MIN, DEC64_MAX};
     68   _Decimal128 d128_in[] = {1234567812345678912345678912.5656789DL,
     69                            DEC128_MIN, DEC128_MAX};
     70 
     71  /* valid function code */
     72   PFPO(0., double, _Decimal64, 0x81090600, 0, ret_code, cc);
     73   printf("pfpo test: function=%x ret=%d cc=%d\n", 0x81090600, ret_code, cc);
     74 
     75  /* invalid function code */
     76   PFPO(0., double, _Decimal64, 0x81990600, 0, ret_code, cc);
     77   printf("pfpo test: function=%x ret=%d cc=%d\n", 0x81990600, ret_code, cc);
     78 
     79   for (i = 0; i < 16; i++) {
     80     if (i < 2 || i > 7) {
     81 
     82       /* f32 -> d32 */
     83       for(j = 0; j < 3; j++) {
     84         printf("f32 -> d32: round=%x ", i);
     85         printf("%f -> ", f32_in[j]);
     86         d32 = PFPO(f32_in[j], float, _Decimal32, PFPO_F32_TO_D32,
     87                    i, ret_code, cc);
     88         DFP_VAL_PRINT(d32, _Decimal32);
     89         printf(" ret=%d cc=%d\n", ret_code, cc);
     90       }
     91 
     92       /* f32 -> d64 */
     93       for(j = 0; j < 3; j++) {
     94         printf("f32 -> d64: round=%x ", i);
     95         printf("%f -> ", f32_in[j]);
     96         d64 = PFPO(f32_in[j], float, _Decimal64, PFPO_F32_TO_D64,
     97                    i, ret_code, cc);
     98         DFP_VAL_PRINT(d64, _Decimal64);
     99         printf(" ret=%d cc=%d\n", ret_code, cc);
    100       }
    101 
    102       /* f32 -> d128 */
    103       for(j = 0; j < 3; j++) {
    104         printf("f32 -> d128: round=%x ", i);
    105         printf("%f -> ", f32_in[j]);
    106         d128 = PFPO(f32_in[j], float, _Decimal128, PFPO_F32_TO_D128,
    107                     i, ret_code, cc);
    108         DFP_VAL_PRINT(d128, _Decimal128);
    109         printf(" ret=%d cc=%d\n", ret_code, cc);
    110       }
    111 
    112       /* f64 -> d32 */
    113       for(j = 0; j < 3; j++) {
    114         printf("f64 -> d32: round=%x ", i);
    115         printf("%lf -> ", f64_in[j]);
    116         d32 = PFPO(f64_in[j], double, _Decimal32, PFPO_F64_TO_D32,
    117                    i, ret_code, cc);
    118         DFP_VAL_PRINT(d32, _Decimal32);
    119         printf(" ret=%d cc=%d\n", ret_code, cc);
    120       }
    121 
    122       /* f64 -> d64 */
    123       for(j = 0; j < 3; j++) {
    124         printf("f64 -> d64: round=%x ", i);
    125         printf("%lf -> ", f64_in[j]);
    126         d64 = PFPO(f64_in[j], double, _Decimal64, PFPO_F64_TO_D64,
    127                    i, ret_code, cc);
    128         DFP_VAL_PRINT(d64, _Decimal64);
    129         printf(" ret=%d cc=%d\n", ret_code, cc);
    130       }
    131 
    132       /* f64 -> d128 */
    133       for(j = 0; j < 3; j++) {
    134         printf("f64 -> d128: round=%x ", i);
    135         printf("%lf -> ", f64_in[j]);
    136         d128 = PFPO(f64_in[j], double, _Decimal128, PFPO_F64_TO_D128,
    137                    i, ret_code, cc);
    138         DFP_VAL_PRINT(d128, _Decimal128);
    139         printf(" ret=%d cc=%d\n", ret_code, cc);
    140       }
    141 
    142       /* f128 -> d32 */
    143       for(j = 0; j < 3; j++) {
    144         printf("f128 -> d32: round=%x ", i);
    145         printf("%Lf -> ", f128_in[j]);
    146         d32 = PFPO(f128_in[j], long double, _Decimal32, PFPO_F128_TO_D32,
    147                    i, ret_code, cc);
    148         DFP_VAL_PRINT(d32, _Decimal32);
    149         printf(" ret=%d cc=%d\n", ret_code, cc);
    150       }
    151 
    152       /* f128 -> d64 */
    153       for(j = 0; j < 3; j++) {
    154         printf("f128 -> d6: round=%x ", i);
    155         printf("%Lf -> ", f128_in[j]);
    156         d64 = PFPO(f128_in[j], long double, _Decimal64, PFPO_F128_TO_D64,
    157                    i, ret_code, cc);
    158         DFP_VAL_PRINT(d64, _Decimal64);
    159         printf(" ret=%d cc=%d\n", ret_code, cc);
    160       }
    161 
    162       /* f128 -> d128 */
    163       for(j = 0; j < 3; j++) {
    164         printf("f128 -> d128: round=%x ", i);
    165         printf("%Lf -> ", f128_in[j]);
    166         d128 = PFPO(f128_in[j], long double, _Decimal128, PFPO_F128_TO_D128,
    167                    i, ret_code, cc);
    168         DFP_VAL_PRINT(d128, _Decimal128);
    169         printf(" ret=%d cc=%d\n", ret_code, cc);
    170       }
    171 
    172       /* d32 -> f32 */
    173       for(j = 0; j < 3; j++) {
    174         printf("d32 -> f32: round=%x ", i);
    175         DFP_VAL_PRINT(d32_in[j], _Decimal32);
    176         printf(" -> ");
    177         f32 = PFPO(d32_in[j], _Decimal32, float, PFPO_D32_TO_F32,
    178                    i, ret_code, cc);
    179         printf("%f", f32);
    180         printf(" ret=%d cc=%d\n", ret_code, cc);
    181       }
    182 
    183       /* d32 -> f64 */
    184       for(j = 0; j < 3; j++) {
    185         printf("d32 -> f64: round=%x ", i);
    186         DFP_VAL_PRINT(d32_in[j], _Decimal32);
    187         printf(" -> ");
    188         f64 = PFPO(d32_in[j], _Decimal32, double, PFPO_D32_TO_F64,
    189                    i, ret_code, cc);
    190         printf("%lf", f64);
    191         printf(" ret=%d cc=%d\n", ret_code, cc);
    192       }
    193 
    194       /* d32 -> f128 */
    195       for(j = 0; j < 3; j++) {
    196         printf("d32 -> f128: round=%x ", i);
    197         DFP_VAL_PRINT(d32_in[j], _Decimal32);
    198         printf(" -> ");
    199         f128 = PFPO(d32_in[j], _Decimal32, long double, PFPO_D32_TO_F128,
    200                    i, ret_code, cc);
    201         printf("%Lf", f128);
    202         printf(" ret=%d cc=%d\n", ret_code, cc);
    203       }
    204 
    205       /* d64 -> f32 */
    206       for(j = 0; j < 3; j++) {
    207         printf("d64 -> f32: round=%x ", i);
    208         DFP_VAL_PRINT(d64_in[j], _Decimal64);
    209         printf(" -> ");
    210         f32 = PFPO(d64_in[j], _Decimal64, float, PFPO_D64_TO_F32,
    211                    i, ret_code, cc);
    212         printf("%f", f32);
    213         printf(" ret=%d cc=%d\n", ret_code, cc);
    214       }
    215 
    216       /* d64 -> f64 */
    217       for(j = 0; j < 3; j++) {
    218         printf("d64 -> f64: round=%x ", i);
    219         DFP_VAL_PRINT(d64_in[j], _Decimal64);
    220         printf(" -> ");
    221         f64 = PFPO(d64_in[j], _Decimal64, double, PFPO_D64_TO_F64,
    222                    i, ret_code, cc);
    223         printf("%lf", f64);
    224         printf(" ret=%d cc=%d\n", ret_code, cc);
    225       }
    226 
    227       /* d64 -> f128 */
    228       for(j = 0; j < 3; j++) {
    229         printf("d64 -> f128: round=%x ", i);
    230         DFP_VAL_PRINT(d64_in[j], _Decimal64);
    231         printf(" -> ");
    232         f128 = PFPO(d64_in[j], _Decimal64, long double, PFPO_D64_TO_F128,
    233                    i, ret_code, cc);
    234         printf("%Lf", f128);
    235         printf(" ret=%d cc=%d\n", ret_code, cc);
    236       }
    237 
    238       /* d128 -> f32 */
    239       for(j = 0; j < 3; j++) {
    240         printf("d128 -> f32: round=%x ", i);
    241         DFP_VAL_PRINT(d128_in[j], _Decimal128);
    242         printf(" -> ");
    243         f32 = PFPO(d128_in[j], _Decimal128, float, PFPO_D128_TO_F32,
    244                    i, ret_code, cc);
    245         printf("%f", f32);
    246         printf(" ret=%d cc=%d\n", ret_code, cc);
    247       }
    248 
    249       /* d128 -> f64 */
    250       for(j = 0; j < 3; j++) {
    251         printf("d128 -> f64: round=%x ", i);
    252         DFP_VAL_PRINT(d128_in[j], _Decimal128);
    253         printf(" -> ");
    254         f64 = PFPO(d128_in[j], _Decimal128, double, PFPO_D128_TO_F64,
    255                    i, ret_code, cc);
    256         printf("%lf", f64);
    257         printf(" ret=%d cc=%d\n", ret_code, cc);
    258       }
    259 
    260       /* d128 -> f128 */
    261       for(j = 0; j < 3; j++) {
    262         printf("d128 -> f128: round=%x ", i);
    263         DFP_VAL_PRINT(d128_in[j], _Decimal128);
    264         printf(" -> ");
    265         f128 = PFPO(d128_in[j], _Decimal128, long double, PFPO_D128_TO_F128,
    266                    i, ret_code, cc);
    267         printf("%Lf", f128);
    268         printf(" ret=%d cc=%d\n", ret_code, cc);
    269       }
    270     }
    271   }
    272   return 0;
    273 }
    274