Home | History | Annotate | Line # | Download | only in common
fpu-tst.c revision 1.6
      1 #define ASSERT(EXPRESSION) \
      2 do { \
      3   if (!(EXPRESSION)) { \
      4     fprintf (stderr, "%s:%d: assertion failed - %s\n", \
      5              __FILE__, __LINE__, #EXPRESSION); \
      6     abort (); \
      7   } \
      8 } while (0)
      9 
     10 #define SIM_BITS_INLINE (INCLUDE_MODULE | INCLUDED_BY_MODULE)
     11 
     12 #include "milieu.h"
     13 #include "softfloat.h"
     14 #include "systfloat.h"
     15 #include "systmodes.h"
     16 
     17 /* #define SIM_FPU_INLINE (INCLUDE_MODULE | INCLUDED_BY_MODULE) */
     18 
     19 
     20 #include "sim-bits.h"
     21 #include "sim-fpu.h"
     22 #include "sim-fpu.c"
     23 
     24 
     25 
     26 static int flags;
     27 
     28 int8_t
     29 syst_float_flags_clear ()
     30 {
     31   int old_flags = 0;
     32   int i = 1;
     33   while (flags >= i)
     34     {
     35       switch ((sim_fpu_status) (flags & i))
     36 	{
     37 	case sim_fpu_status_denorm:
     38 	  break;
     39 	case sim_fpu_status_invalid_snan:
     40 	case sim_fpu_status_invalid_qnan:
     41 	case sim_fpu_status_invalid_isi:
     42 	case sim_fpu_status_invalid_idi:
     43 	case sim_fpu_status_invalid_zdz:
     44 	case sim_fpu_status_invalid_imz:
     45 	case sim_fpu_status_invalid_cvi:
     46 	case sim_fpu_status_invalid_cmp:
     47 	case sim_fpu_status_invalid_sqrt:
     48 	  old_flags |= float_flag_invalid; /* v */
     49 	  break;
     50 	case sim_fpu_status_inexact:
     51 	  old_flags |= float_flag_inexact; /* x */
     52 	  break;
     53 	case sim_fpu_status_overflow:
     54 	  old_flags |= float_flag_overflow; /* o */
     55 	  break;
     56 	case sim_fpu_status_underflow:
     57 	  old_flags |= float_flag_underflow; /* u */
     58 	  break;
     59 	case sim_fpu_status_invalid_div0:
     60 	  old_flags |= float_flag_divbyzero; /* z */
     61 	  break;
     62 	case sim_fpu_status_rounded:
     63 	  break;
     64 	}
     65       i <<= 1;
     66     }
     67   flags = 0;
     68   return old_flags;
     69 }
     70 
     71 
     72 sim_fpu_round rounding_mode;
     73 
     74 void
     75 syst_float_set_rounding_mode(int8_t mode)
     76 {
     77   switch (mode)
     78     {
     79     case float_round_nearest_even:
     80       rounding_mode = sim_fpu_round_near;
     81       break;
     82     case float_round_down:
     83       rounding_mode = sim_fpu_round_down;
     84       break;
     85     case float_round_up:
     86       rounding_mode = sim_fpu_round_up;
     87       break;
     88     case float_round_to_zero:
     89       rounding_mode = sim_fpu_round_zero;
     90       break;
     91     }
     92 }
     93 
     94 
     95 float32
     96 syst_int32_to_float32(int32_t a)
     97 {
     98   float32 z;
     99   sim_fpu s;
    100   flags |= sim_fpu_i32to (&s, a, rounding_mode);
    101   flags |= sim_fpu_round_32 (&s, rounding_mode, 0);
    102   sim_fpu_to32 (&z, &s);
    103   return z;
    104 }
    105 
    106 float64
    107 syst_int32_to_float64( int32_t a )
    108 {
    109   float64 z;
    110   sim_fpu s;
    111   flags |= sim_fpu_i32to (&s, a, rounding_mode);
    112   sim_fpu_to64 (&z, &s);
    113   return z;
    114 }
    115 
    116 int32_t
    117 syst_float32_to_int32_round_to_zero( float32 a )
    118 {
    119   int32_t z;
    120   sim_fpu s;
    121   sim_fpu_32to (&s, a);
    122   flags |= sim_fpu_to32i (&z, &s, sim_fpu_round_zero);
    123   return z;
    124 }
    125 
    126 float64
    127 syst_float32_to_float64 (float32 a)
    128 {
    129   float64 z;
    130   sim_fpu s;
    131   sim_fpu_32to (&s, a);
    132   flags |= sim_fpu_round_64 (&s, rounding_mode, 0);
    133   sim_fpu_to64 (&z, &s);
    134   return z;
    135 }
    136 
    137 float32 syst_float32_add( float32 a, float32 b )
    138 {
    139   float32 z;
    140   sim_fpu A;
    141   sim_fpu B;
    142   sim_fpu ans;
    143   sim_fpu_32to (&A, a);
    144   sim_fpu_32to (&B, b);
    145 #if 0
    146   fprintf (stdout, "\n  ");
    147   sim_fpu_print_fpu (&A, (sim_fpu_print_func*) fprintf, stdout);
    148   fprintf (stdout, "\n+ ");
    149   sim_fpu_print_fpu (&B, (sim_fpu_print_func*) fprintf, stdout);
    150   fprintf (stdout, "\n= ");
    151 #endif
    152   flags |= sim_fpu_add (&ans, &A, &B);
    153   flags |= sim_fpu_round_32 (&ans, rounding_mode, 0);
    154 #if 0
    155   sim_fpu_print_fpu (&ans, (sim_fpu_print_func*) fprintf, stdout);
    156   fprintf (stdout, "\n");
    157 #endif
    158   sim_fpu_to32 (&z, &ans);
    159   return z;
    160 }
    161 
    162 float32 syst_float32_sub( float32 a, float32 b )
    163 {
    164   float32 z;
    165   sim_fpu A;
    166   sim_fpu B;
    167   sim_fpu ans;
    168   sim_fpu_32to (&A, a);
    169   sim_fpu_32to (&B, b);
    170 #if 0
    171   sim_fpu_print_fpu (&A, (sim_fpu_print_func*) fprintf, stdout);
    172   fprintf (stdout, " + ");
    173   sim_fpu_print_fpu (&B, (sim_fpu_print_func*) fprintf, stdout);
    174   fprintf (stdout, " = ");
    175 #endif
    176   flags |= sim_fpu_sub (&ans, &A, &B);
    177   flags |= sim_fpu_round_32 (&ans, rounding_mode, 0);
    178 #if 0
    179   sim_fpu_print_fpu (&ans, (sim_fpu_print_func*) fprintf, stdout);
    180   fprintf (stdout, "\n");
    181 #endif
    182   sim_fpu_to32 (&z, &ans);
    183   return z;
    184 }
    185 
    186 float32 syst_float32_mul( float32 a, float32 b )
    187 {
    188   float32 z;
    189   sim_fpu A;
    190   sim_fpu B;
    191   sim_fpu ans;
    192   sim_fpu_32to (&A, a);
    193   sim_fpu_32to (&B, b);
    194 #if 0
    195   sim_fpu_print_fpu (&A, (sim_fpu_print_func*) fprintf, stdout);
    196   fprintf (stdout, " + ");
    197   sim_fpu_print_fpu (&B, (sim_fpu_print_func*) fprintf, stdout);
    198   fprintf (stdout, " = ");
    199 #endif
    200   flags |= sim_fpu_mul (&ans, &A, &B);
    201 #if 0
    202   sim_fpu_print_fpu (&ans, (sim_fpu_print_func*) fprintf, stdout);
    203 #endif
    204   flags |= sim_fpu_round_32 (&ans, rounding_mode, 0);
    205 #if 0
    206   sim_fpu_print_status (flags, (sim_fpu_print_func*) fprintf, stdout);
    207   fprintf (stdout, "\n");
    208 #endif
    209   sim_fpu_to32 (&z, &ans);
    210   return z;
    211 }
    212 
    213 float32 syst_float32_div( float32 a, float32 b )
    214 {
    215   float32 z;
    216   sim_fpu A;
    217   sim_fpu B;
    218   sim_fpu ans;
    219   sim_fpu_32to (&A, a);
    220   sim_fpu_32to (&B, b);
    221   flags |= sim_fpu_div (&ans, &A, &B);
    222   flags |= sim_fpu_round_32 (&ans, rounding_mode, 0);
    223   sim_fpu_to32 (&z, &ans);
    224   return z;
    225 }
    226 
    227 float32 syst_float32_sqrt( float32 a )
    228 {
    229   float32 z;
    230   sim_fpu A;
    231   sim_fpu ans;
    232   sim_fpu_32to (&A, a);
    233 #if 0
    234   sim_fpu_print_fpu (&A, (sim_fpu_print_func*) fprintf, stdout);
    235   fprintf (stdout, " sqrt> ");
    236 #endif
    237   flags |= sim_fpu_sqrt (&ans, &A);
    238 #if 0
    239   sim_fpu_print_fpu (&ans, (sim_fpu_print_func*) fprintf, stdout);
    240 #endif
    241   flags |= sim_fpu_round_32 (&ans, rounding_mode, 0);
    242 #if 0
    243   fprintf (stdout, " (%x)\n", flags);
    244 #endif
    245   sim_fpu_to32 (&z, &ans);
    246   return z;
    247 }
    248 
    249 flag syst_float32_eq( float32 a, float32 b )
    250 {
    251   sim_fpu A;
    252   sim_fpu B;
    253   int is;
    254   sim_fpu_32to (&A, a);
    255   sim_fpu_32to (&B, b);
    256   flags |= (sim_fpu_eq (&is, &A, &B) & ~sim_fpu_status_invalid_qnan);
    257   return is;
    258 }
    259 
    260 flag syst_float32_eq_signaling( float32 a, float32 b )
    261 {
    262   sim_fpu A;
    263   sim_fpu B;
    264   int is;
    265   sim_fpu_32to (&A, a);
    266   sim_fpu_32to (&B, b);
    267   flags |= sim_fpu_eq (&is, &A, &B);
    268   return is;
    269 }
    270 
    271 flag syst_float32_le( float32 a, float32 b )
    272 {
    273   sim_fpu A;
    274   sim_fpu B;
    275   int is;
    276   sim_fpu_32to (&A, a);
    277   sim_fpu_32to (&B, b);
    278   flags |= sim_fpu_le (&is, &A, &B);
    279   return is;
    280 }
    281 
    282 flag syst_float32_le_quiet( float32 a, float32 b )
    283 {
    284   sim_fpu A;
    285   sim_fpu B;
    286   int is;
    287   sim_fpu_32to (&A, a);
    288   sim_fpu_32to (&B, b);
    289   flags |= (sim_fpu_le (&is, &A, &B) & ~sim_fpu_status_invalid_qnan);
    290   return is;
    291 }
    292 
    293 flag syst_float32_lt( float32 a, float32 b )
    294 {
    295   sim_fpu A;
    296   sim_fpu B;
    297   int is;
    298   sim_fpu_32to (&A, a);
    299   sim_fpu_32to (&B, b);
    300   flags |= sim_fpu_lt (&is, &A, &B);
    301   return is;
    302 }
    303 
    304 flag syst_float32_lt_quiet( float32 a, float32 b )
    305 {
    306   sim_fpu A;
    307   sim_fpu B;
    308   int is;
    309   sim_fpu_32to (&A, a);
    310   sim_fpu_32to (&B, b);
    311   flags |= (sim_fpu_lt (&is, &A, &B) & ~sim_fpu_status_invalid_qnan);
    312   return is;
    313 }
    314 
    315 int32_t syst_float64_to_int32_round_to_zero( float64 a )
    316 {
    317   int32_t z;
    318   sim_fpu s;
    319   sim_fpu_64to (&s, a);
    320   flags |= sim_fpu_to32i (&z, &s, sim_fpu_round_zero);
    321   return z;
    322 }
    323 
    324 float32 syst_float64_to_float32( float64 a )
    325 {
    326   float32 z;
    327   sim_fpu s;
    328   sim_fpu_64to (&s, a);
    329 #if 0
    330   sim_fpu_print_fpu (&s, (sim_fpu_print_func*) fprintf, stdout);
    331   fprintf (stdout, " -> ");
    332 #endif
    333   flags |= sim_fpu_round_32 (&s, rounding_mode, 0);
    334 #if 0
    335   sim_fpu_print_fpu (&s, (sim_fpu_print_func*) fprintf, stdout);
    336   sim_fpu_print_status (flags, (sim_fpu_print_func*) fprintf, stdout);
    337   printf ("\n");
    338 #endif
    339   sim_fpu_to32 (&z, &s);
    340   return z;
    341 }
    342 
    343 float64 syst_float64_add( float64 a, float64 b )
    344 {
    345   float64 z;
    346   sim_fpu A;
    347   sim_fpu B;
    348   sim_fpu ans;
    349   sim_fpu_64to (&A, a);
    350   sim_fpu_64to (&B, b);
    351 #if 0
    352   sim_fpu_print_fpu (&A, (sim_fpu_print_func*) fprintf, stdout);
    353   fprintf (stdout, " + ");
    354   sim_fpu_print_fpu (&B, (sim_fpu_print_func*) fprintf, stdout);
    355   fprintf (stdout, " = ");
    356 #endif
    357   flags |= sim_fpu_add (&ans, &A, &B);
    358 #if 0
    359   sim_fpu_print_fpu (&ans, (sim_fpu_print_func*) fprintf, stdout);
    360 #endif
    361   flags |= sim_fpu_round_64 (&ans, rounding_mode, 0);
    362 #if 0
    363   fprintf (stdout, " (%x)\n", flags);
    364 #endif
    365   sim_fpu_to64 (&z, &ans);
    366   return z;
    367 }
    368 
    369 float64 syst_float64_sub( float64 a, float64 b )
    370 {
    371   float64 z;
    372   sim_fpu A;
    373   sim_fpu B;
    374   sim_fpu ans;
    375   sim_fpu_64to (&A, a);
    376   sim_fpu_64to (&B, b);
    377 #if 0
    378   sim_fpu_print_fpu (&A, (sim_fpu_print_func*) fprintf, stdout);
    379   fprintf (stdout, " + ");
    380   sim_fpu_print_fpu (&B, (sim_fpu_print_func*) fprintf, stdout);
    381   fprintf (stdout, " = ");
    382 #endif
    383   flags |= sim_fpu_sub (&ans, &A, &B);
    384 #if 0
    385   sim_fpu_print_fpu (&ans, (sim_fpu_print_func*) fprintf, stdout);
    386 #endif
    387   flags |= sim_fpu_round_64 (&ans, rounding_mode, 0);
    388 #if 0
    389   fprintf (stdout, " (%x)\n", flags);
    390 #endif
    391   sim_fpu_to64 (&z, &ans);
    392   return z;
    393 }
    394 
    395 float64 syst_float64_mul( float64 a, float64 b )
    396 {
    397   float64 z;
    398   sim_fpu A;
    399   sim_fpu B;
    400   sim_fpu ans;
    401   sim_fpu_64to (&A, a);
    402   sim_fpu_64to (&B, b);
    403 #if 0
    404   sim_fpu_print_fpu (&A, (sim_fpu_print_func*) fprintf, stdout);
    405   fprintf (stdout, " * ");
    406   sim_fpu_print_fpu (&B, (sim_fpu_print_func*) fprintf, stdout);
    407   fprintf (stdout, " = ");
    408 #endif
    409   flags |= sim_fpu_mul (&ans, &A, &B);
    410 #if 0
    411   sim_fpu_print_fpu (&ans, (sim_fpu_print_func*) fprintf, stdout);
    412 #endif
    413   flags |= sim_fpu_round_64 (&ans, rounding_mode, 0);
    414 #if 0
    415   sim_fpu_print_status (flags, (sim_fpu_print_func*) fprintf, stdout);
    416   fprintf (stdout, "\n");
    417 #endif
    418   sim_fpu_to64 (&z, &ans);
    419   return z;
    420 }
    421 
    422 float64 syst_float64_div( float64 a, float64 b )
    423 {
    424   float64 z;
    425   sim_fpu A;
    426   sim_fpu B;
    427   sim_fpu ans;
    428   sim_fpu_64to (&A, a);
    429   sim_fpu_64to (&B, b);
    430 #if 0
    431   sim_fpu_print_fpu (&A, (sim_fpu_print_func*) fprintf, stdout);
    432   fprintf (stdout, " + ");
    433   sim_fpu_print_fpu (&B, (sim_fpu_print_func*) fprintf, stdout);
    434   fprintf (stdout, " = ");
    435 #endif
    436   flags |= sim_fpu_div (&ans, &A, &B);
    437 #if 0
    438   sim_fpu_print_fpu (&ans, (sim_fpu_print_func*) fprintf, stdout);
    439 #endif
    440   flags |= sim_fpu_round_64 (&ans, rounding_mode, 0);
    441 #if 0
    442   sim_fpu_print_status (flags, (sim_fpu_print_func*) fprintf, stdout);
    443   fprintf (stdout, "\n");
    444 #endif
    445   sim_fpu_to64 (&z, &ans);
    446   return z;
    447 }
    448 
    449 float64 syst_float64_sqrt( float64 a )
    450 {
    451   float64 z;
    452   sim_fpu A;
    453   sim_fpu ans;
    454   sim_fpu_64to (&A, a);
    455 #if 0
    456   sim_fpu_print_fpu (&A, (sim_fpu_print_func*) fprintf, stdout);
    457   printf (" sqrt> ");
    458   printf ("\n");
    459 #endif
    460   flags |= sim_fpu_sqrt (&ans, &A);
    461 #if 0
    462   sim_fpu_print_fpu (&ans, (sim_fpu_print_func*) fprintf, stdout);
    463 #endif
    464   flags |= sim_fpu_round_64 (&ans, rounding_mode, 0);
    465 #if 0
    466   sim_fpu_print_status (flags, (sim_fpu_print_func*) fprintf, stdout);
    467   fprintf (stdout, "\n");
    468 #endif
    469   sim_fpu_to64 (&z, &ans);
    470   return z;
    471 }
    472 
    473 flag syst_float64_eq( float64 a, float64 b )
    474 {
    475   sim_fpu A;
    476   sim_fpu B;
    477   int is;
    478   sim_fpu_64to (&A, a);
    479   sim_fpu_64to (&B, b);
    480   flags |= (sim_fpu_eq (&is, &A, &B) & ~sim_fpu_status_invalid_qnan);
    481   return is;
    482 }
    483 
    484 flag syst_float64_eq_signaling( float64 a, float64 b )
    485 {
    486   sim_fpu A;
    487   sim_fpu B;
    488   int is;
    489   sim_fpu_64to (&A, a);
    490   sim_fpu_64to (&B, b);
    491   flags |= sim_fpu_eq (&is, &A, &B);
    492   return is;
    493 }
    494 
    495 flag syst_float64_le( float64 a, float64 b )
    496 {
    497   sim_fpu A;
    498   sim_fpu B;
    499   int is;
    500   sim_fpu_64to (&A, a);
    501   sim_fpu_64to (&B, b);
    502   flags |= sim_fpu_le (&is, &A, &B);
    503   return is;
    504 }
    505 
    506 flag syst_float64_le_quiet( float64 a, float64 b )
    507 {
    508   sim_fpu A;
    509   sim_fpu B;
    510   int is;
    511   sim_fpu_64to (&A, a);
    512   sim_fpu_64to (&B, b);
    513   flags |= (sim_fpu_le (&is, &A, &B) & ~sim_fpu_status_invalid_qnan);
    514   return is;
    515 }
    516 
    517 flag syst_float64_lt( float64 a, float64 b )
    518 {
    519   sim_fpu A;
    520   sim_fpu B;
    521   int is;
    522   sim_fpu_64to (&A, a);
    523   sim_fpu_64to (&B, b);
    524   flags |= sim_fpu_lt (&is, &A, &B);
    525   return is;
    526 }
    527 
    528 flag syst_float64_lt_quiet( float64 a, float64 b )
    529 {
    530   sim_fpu A;
    531   sim_fpu B;
    532   int is;
    533   sim_fpu_64to (&A, a);
    534   sim_fpu_64to (&B, b);
    535   flags |= (sim_fpu_lt (&is, &A, &B) & ~sim_fpu_status_invalid_qnan);
    536   return is;
    537 }
    538 
    539