qemu

FORK: QEMU emulator
git clone https://git.neptards.moe/neptards/qemu.git
Log | Files | Refs | Submodules | LICENSE

float_convs.c (2807B)


      1 /*
      2  * Floating Point Convert Single to Various
      3  *
      4  * Copyright (c) 2019 Linaro
      5  *
      6  * SPDX-License-Identifier: GPL-3.0-or-later
      7  */
      8 
      9 #include <stdio.h>
     10 #include <stdlib.h>
     11 #include <math.h>
     12 #include <float.h>
     13 #include <fenv.h>
     14 
     15 
     16 #include "float_helpers.h"
     17 
     18 #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
     19 
     20 typedef struct {
     21     int flag;
     22     char *desc;
     23 } float_mapping;
     24 
     25 float_mapping round_flags[] = {
     26     { FE_TONEAREST, "to nearest" },
     27 #ifdef FE_UPWARD
     28     { FE_UPWARD, "upwards" },
     29 #endif
     30 #ifdef FE_DOWNWARD
     31     { FE_DOWNWARD, "downwards" },
     32 #endif
     33 #ifdef FE_TOWARDZERO
     34     { FE_TOWARDZERO, "to zero" }
     35 #endif
     36 };
     37 
     38 static void print_input(float input)
     39 {
     40     char *in_fmt = fmt_f32(input);
     41     printf("from single: %s\n", in_fmt);
     42     free(in_fmt);
     43 }
     44 
     45 static void convert_single_to_double(float input)
     46 {
     47     double output;
     48     char *out_fmt, *flag_fmt;
     49 
     50     feclearexcept(FE_ALL_EXCEPT);
     51 
     52     output = input;
     53 
     54     flag_fmt = fmt_flags();
     55     out_fmt = fmt_f64(output);
     56     printf("  to double: %s (%s)\n", out_fmt, flag_fmt);
     57     free(out_fmt);
     58     free(flag_fmt);
     59 }
     60 
     61 #define xstr(a) str(a)
     62 #define str(a) #a
     63 
     64 #define CONVERT_SINGLE_TO_INT(TYPE, FMT)                            \
     65     static void convert_single_to_ ## TYPE(float input)             \
     66     {                                                               \
     67         TYPE ## _t output;                                          \
     68         char *flag_fmt;                                             \
     69         const char to[] = "to " xstr(TYPE);                         \
     70         feclearexcept(FE_ALL_EXCEPT);                               \
     71         output = input;                                             \
     72         flag_fmt = fmt_flags();                                     \
     73         printf("%11s: %" FMT " (%s)\n", to, output, flag_fmt);      \
     74         free(flag_fmt);                                             \
     75     }
     76 
     77 CONVERT_SINGLE_TO_INT( int32, PRId32)
     78 CONVERT_SINGLE_TO_INT(uint32, PRId32)
     79 CONVERT_SINGLE_TO_INT( int64, PRId64)
     80 CONVERT_SINGLE_TO_INT(uint64, PRId64)
     81 
     82 int main(int argc, char *argv[argc])
     83 {
     84     int i, j, nums;
     85 
     86     nums = get_num_f32();
     87 
     88     for (i = 0; i < ARRAY_SIZE(round_flags); ++i) {
     89         if (fesetround(round_flags[i].flag) != 0) {
     90             printf("### Rounding %s skipped\n", round_flags[i].desc);
     91             continue;
     92         }
     93         printf("### Rounding %s\n", round_flags[i].desc);
     94         for (j = 0; j < nums; j++) {
     95             float input = get_f32(j);
     96             print_input(input);
     97             /* convert_single_to_half(input); */
     98             convert_single_to_double(input);
     99             convert_single_to_int32(input);
    100             convert_single_to_int64(input);
    101             convert_single_to_uint32(input);
    102             convert_single_to_uint64(input);
    103         }
    104     }
    105 
    106     return 0;
    107 }