Home | History | Annotate | Line # | Download | only in common
      1      1.1  christos /* Accurate fp support for CGEN-based simulators.
      2      1.1  christos    Copyright (C) 1999 Cygnus Solutions.
      3      1.1  christos 
      4      1.1  christos    This implemention assumes:
      5      1.1  christos    typedef USI SF;
      6      1.1  christos    typedef UDI DF;
      7      1.1  christos 
      8      1.1  christos    TODO:
      9      1.1  christos    - lazy encoding/decoding
     10      1.1  christos    - checking return code (say by callback)
     11      1.1  christos    - proper rounding
     12      1.1  christos */
     13      1.1  christos 
     14  1.1.1.4  christos /* This must come before any other includes.  */
     15  1.1.1.4  christos #include "defs.h"
     16  1.1.1.4  christos 
     17      1.1  christos #include "sim-main.h"
     18      1.1  christos #include "sim-fpu.h"
     19      1.1  christos 
     20      1.1  christos /* SF mode support */
     21      1.1  christos 
     22      1.1  christos static SF
     23      1.1  christos addsf (CGEN_FPU* fpu, SF x, SF y)
     24      1.1  christos {
     25      1.1  christos   sim_fpu op1;
     26      1.1  christos   sim_fpu op2;
     27      1.1  christos   sim_fpu ans;
     28  1.1.1.4  christos   uint32_t res;
     29      1.1  christos   sim_fpu_status status;
     30      1.1  christos 
     31      1.1  christos   sim_fpu_32to (&op1, x);
     32      1.1  christos   sim_fpu_32to (&op2, y);
     33      1.1  christos   status = sim_fpu_add (&ans, &op1, &op2);
     34      1.1  christos   if (status != 0)
     35      1.1  christos     (*fpu->ops->error) (fpu, status);
     36      1.1  christos   sim_fpu_to32 (&res, &ans);
     37      1.1  christos 
     38      1.1  christos   return res;
     39      1.1  christos }
     40      1.1  christos 
     41      1.1  christos static SF
     42      1.1  christos subsf (CGEN_FPU* fpu, SF x, SF y)
     43      1.1  christos {
     44      1.1  christos   sim_fpu op1;
     45      1.1  christos   sim_fpu op2;
     46      1.1  christos   sim_fpu ans;
     47  1.1.1.4  christos   uint32_t res;
     48      1.1  christos   sim_fpu_status status;
     49      1.1  christos 
     50      1.1  christos   sim_fpu_32to (&op1, x);
     51      1.1  christos   sim_fpu_32to (&op2, y);
     52      1.1  christos   status = sim_fpu_sub (&ans, &op1, &op2);
     53      1.1  christos   if (status != 0)
     54      1.1  christos     (*fpu->ops->error) (fpu, status);
     55      1.1  christos   sim_fpu_to32 (&res, &ans);
     56      1.1  christos 
     57      1.1  christos   return res;
     58      1.1  christos }
     59      1.1  christos 
     60      1.1  christos static SF
     61      1.1  christos mulsf (CGEN_FPU* fpu, SF x, SF y)
     62      1.1  christos {
     63      1.1  christos   sim_fpu op1;
     64      1.1  christos   sim_fpu op2;
     65      1.1  christos   sim_fpu ans;
     66  1.1.1.4  christos   uint32_t res;
     67      1.1  christos   sim_fpu_status status;
     68      1.1  christos 
     69      1.1  christos   sim_fpu_32to (&op1, x);
     70      1.1  christos   sim_fpu_32to (&op2, y);
     71      1.1  christos   status = sim_fpu_mul (&ans, &op1, &op2);
     72      1.1  christos   if (status != 0)
     73      1.1  christos     (*fpu->ops->error) (fpu, status);
     74      1.1  christos   sim_fpu_to32 (&res, &ans);
     75      1.1  christos 
     76      1.1  christos   return res;
     77      1.1  christos }
     78      1.1  christos 
     79      1.1  christos static SF
     80      1.1  christos divsf (CGEN_FPU* fpu, SF x, SF y)
     81      1.1  christos {
     82      1.1  christos   sim_fpu op1;
     83      1.1  christos   sim_fpu op2;
     84      1.1  christos   sim_fpu ans;
     85  1.1.1.4  christos   uint32_t res;
     86      1.1  christos   sim_fpu_status status;
     87      1.1  christos 
     88      1.1  christos   sim_fpu_32to (&op1, x);
     89      1.1  christos   sim_fpu_32to (&op2, y);
     90      1.1  christos   status = sim_fpu_div (&ans, &op1, &op2);
     91      1.1  christos   if (status != 0)
     92      1.1  christos     (*fpu->ops->error) (fpu, status);
     93      1.1  christos   sim_fpu_to32 (&res, &ans);
     94      1.1  christos 
     95      1.1  christos   return res;
     96      1.1  christos }
     97      1.1  christos 
     98      1.1  christos static SF
     99  1.1.1.2  christos remsf (CGEN_FPU* fpu, SF x, SF y)
    100  1.1.1.2  christos {
    101  1.1.1.2  christos   sim_fpu op1;
    102  1.1.1.2  christos   sim_fpu op2;
    103  1.1.1.2  christos   sim_fpu ans;
    104  1.1.1.4  christos   uint32_t res;
    105  1.1.1.2  christos   sim_fpu_status status;
    106  1.1.1.2  christos 
    107  1.1.1.2  christos   sim_fpu_32to (&op1, x);
    108  1.1.1.2  christos   sim_fpu_32to (&op2, y);
    109  1.1.1.2  christos   status = sim_fpu_rem (&ans, &op1, &op2);
    110  1.1.1.2  christos   if (status != 0)
    111  1.1.1.2  christos     (*fpu->ops->error) (fpu, status);
    112  1.1.1.2  christos   sim_fpu_to32 (&res, &ans);
    113  1.1.1.2  christos 
    114  1.1.1.2  christos   return res;
    115  1.1.1.2  christos }
    116  1.1.1.2  christos 
    117  1.1.1.2  christos static SF
    118      1.1  christos negsf (CGEN_FPU* fpu, SF x)
    119      1.1  christos {
    120      1.1  christos   sim_fpu op1;
    121      1.1  christos   sim_fpu ans;
    122  1.1.1.4  christos   uint32_t res;
    123      1.1  christos   sim_fpu_status status;
    124      1.1  christos 
    125      1.1  christos   sim_fpu_32to (&op1, x);
    126      1.1  christos   status = sim_fpu_neg (&ans, &op1);
    127      1.1  christos   if (status != 0)
    128      1.1  christos     (*fpu->ops->error) (fpu, status);
    129      1.1  christos   sim_fpu_to32 (&res, &ans);
    130      1.1  christos 
    131      1.1  christos   return res;
    132      1.1  christos }
    133      1.1  christos 
    134      1.1  christos static SF
    135      1.1  christos abssf (CGEN_FPU* fpu, SF x)
    136      1.1  christos {
    137      1.1  christos   sim_fpu op1;
    138      1.1  christos   sim_fpu ans;
    139  1.1.1.4  christos   uint32_t res;
    140      1.1  christos   sim_fpu_status status;
    141      1.1  christos 
    142      1.1  christos   sim_fpu_32to (&op1, x);
    143      1.1  christos   status = sim_fpu_abs (&ans, &op1);
    144      1.1  christos   if (status != 0)
    145      1.1  christos     (*fpu->ops->error) (fpu, status);
    146      1.1  christos   sim_fpu_to32 (&res, &ans);
    147      1.1  christos 
    148      1.1  christos   return res;
    149      1.1  christos }
    150      1.1  christos 
    151      1.1  christos static SF
    152      1.1  christos sqrtsf (CGEN_FPU* fpu, SF x)
    153      1.1  christos {
    154      1.1  christos   sim_fpu op1;
    155      1.1  christos   sim_fpu ans;
    156  1.1.1.4  christos   uint32_t res;
    157      1.1  christos   sim_fpu_status status;
    158      1.1  christos 
    159      1.1  christos   sim_fpu_32to (&op1, x);
    160      1.1  christos   status = sim_fpu_sqrt (&ans, &op1);
    161      1.1  christos   if (status != 0)
    162      1.1  christos     (*fpu->ops->error) (fpu, status);
    163      1.1  christos   sim_fpu_to32 (&res, &ans);
    164      1.1  christos 
    165      1.1  christos   return res;
    166      1.1  christos }
    167      1.1  christos 
    168      1.1  christos static SF
    169      1.1  christos invsf (CGEN_FPU* fpu, SF x)
    170      1.1  christos {
    171      1.1  christos   sim_fpu op1;
    172      1.1  christos   sim_fpu ans;
    173  1.1.1.4  christos   uint32_t res;
    174      1.1  christos   sim_fpu_status status;
    175      1.1  christos 
    176      1.1  christos   sim_fpu_32to (&op1, x);
    177      1.1  christos   status = sim_fpu_inv (&ans, &op1);
    178      1.1  christos   if (status != 0)
    179      1.1  christos     (*fpu->ops->error) (fpu, status);
    180      1.1  christos   sim_fpu_to32 (&res, &ans);
    181      1.1  christos 
    182      1.1  christos   return res;
    183      1.1  christos }
    184      1.1  christos 
    185      1.1  christos static SF
    186      1.1  christos minsf (CGEN_FPU* fpu, SF x, SF y)
    187      1.1  christos {
    188      1.1  christos   sim_fpu op1;
    189      1.1  christos   sim_fpu op2;
    190      1.1  christos   sim_fpu ans;
    191  1.1.1.4  christos   uint32_t res;
    192      1.1  christos   sim_fpu_status status;
    193      1.1  christos 
    194      1.1  christos   sim_fpu_32to (&op1, x);
    195      1.1  christos   sim_fpu_32to (&op2, y);
    196      1.1  christos   status = sim_fpu_min (&ans, &op1, &op2);
    197      1.1  christos   if (status != 0)
    198      1.1  christos     (*fpu->ops->error) (fpu, status);
    199      1.1  christos   sim_fpu_to32 (&res, &ans);
    200      1.1  christos 
    201      1.1  christos   return res;
    202      1.1  christos }
    203      1.1  christos 
    204      1.1  christos static SF
    205      1.1  christos maxsf (CGEN_FPU* fpu, SF x, SF y)
    206      1.1  christos {
    207      1.1  christos   sim_fpu op1;
    208      1.1  christos   sim_fpu op2;
    209      1.1  christos   sim_fpu ans;
    210  1.1.1.4  christos   uint32_t res;
    211      1.1  christos   sim_fpu_status status;
    212      1.1  christos 
    213      1.1  christos   sim_fpu_32to (&op1, x);
    214      1.1  christos   sim_fpu_32to (&op2, y);
    215      1.1  christos   status = sim_fpu_max (&ans, &op1, &op2);
    216      1.1  christos   if (status != 0)
    217      1.1  christos     (*fpu->ops->error) (fpu, status);
    218      1.1  christos   sim_fpu_to32 (&res, &ans);
    219      1.1  christos 
    220      1.1  christos   return res;
    221      1.1  christos }
    222      1.1  christos 
    223      1.1  christos static CGEN_FP_CMP
    224      1.1  christos cmpsf (CGEN_FPU* fpu, SF x, SF y)
    225      1.1  christos {
    226      1.1  christos   sim_fpu op1;
    227      1.1  christos   sim_fpu op2;
    228      1.1  christos 
    229      1.1  christos   sim_fpu_32to (&op1, x);
    230      1.1  christos   sim_fpu_32to (&op2, y);
    231      1.1  christos 
    232      1.1  christos   if (sim_fpu_is_nan (&op1)
    233      1.1  christos       || sim_fpu_is_nan (&op2))
    234      1.1  christos     return FP_CMP_NAN;
    235      1.1  christos 
    236      1.1  christos   if (x < y)
    237      1.1  christos     return FP_CMP_LT;
    238      1.1  christos   if (x > y)
    239      1.1  christos     return FP_CMP_GT;
    240      1.1  christos   return FP_CMP_EQ;
    241      1.1  christos }
    242      1.1  christos 
    243      1.1  christos static int
    244      1.1  christos eqsf (CGEN_FPU* fpu, SF x, SF y)
    245      1.1  christos {
    246      1.1  christos   sim_fpu op1;
    247      1.1  christos   sim_fpu op2;
    248      1.1  christos 
    249      1.1  christos   sim_fpu_32to (&op1, x);
    250      1.1  christos   sim_fpu_32to (&op2, y);
    251      1.1  christos   return sim_fpu_is_eq (&op1, &op2);
    252      1.1  christos }
    253      1.1  christos 
    254      1.1  christos static int
    255      1.1  christos nesf (CGEN_FPU* fpu, SF x, SF y)
    256      1.1  christos {
    257      1.1  christos   sim_fpu op1;
    258      1.1  christos   sim_fpu op2;
    259      1.1  christos 
    260      1.1  christos   sim_fpu_32to (&op1, x);
    261      1.1  christos   sim_fpu_32to (&op2, y);
    262      1.1  christos   return sim_fpu_is_ne (&op1, &op2);
    263      1.1  christos }
    264      1.1  christos 
    265      1.1  christos static int
    266      1.1  christos ltsf (CGEN_FPU* fpu, SF x, SF y)
    267      1.1  christos {
    268      1.1  christos   sim_fpu op1;
    269      1.1  christos   sim_fpu op2;
    270      1.1  christos 
    271      1.1  christos   sim_fpu_32to (&op1, x);
    272      1.1  christos   sim_fpu_32to (&op2, y);
    273      1.1  christos   return sim_fpu_is_lt (&op1, &op2);
    274      1.1  christos }
    275      1.1  christos 
    276      1.1  christos static int
    277      1.1  christos lesf (CGEN_FPU* fpu, SF x, SF y)
    278      1.1  christos {
    279      1.1  christos   sim_fpu op1;
    280      1.1  christos   sim_fpu op2;
    281      1.1  christos 
    282      1.1  christos   sim_fpu_32to (&op1, x);
    283      1.1  christos   sim_fpu_32to (&op2, y);
    284      1.1  christos   return sim_fpu_is_le (&op1, &op2);
    285      1.1  christos }
    286      1.1  christos 
    287      1.1  christos static int
    288      1.1  christos gtsf (CGEN_FPU* fpu, SF x, SF y)
    289      1.1  christos {
    290      1.1  christos   sim_fpu op1;
    291      1.1  christos   sim_fpu op2;
    292      1.1  christos 
    293      1.1  christos   sim_fpu_32to (&op1, x);
    294      1.1  christos   sim_fpu_32to (&op2, y);
    295      1.1  christos   return sim_fpu_is_gt (&op1, &op2);
    296      1.1  christos }
    297      1.1  christos 
    298      1.1  christos static int
    299      1.1  christos gesf (CGEN_FPU* fpu, SF x, SF y)
    300      1.1  christos {
    301      1.1  christos   sim_fpu op1;
    302      1.1  christos   sim_fpu op2;
    303      1.1  christos 
    304      1.1  christos   sim_fpu_32to (&op1, x);
    305      1.1  christos   sim_fpu_32to (&op2, y);
    306      1.1  christos   return sim_fpu_is_ge (&op1, &op2);
    307      1.1  christos }
    308      1.1  christos 
    309  1.1.1.3  christos static int
    310  1.1.1.3  christos unorderedsf (CGEN_FPU* fpu, SF x, SF y)
    311  1.1.1.3  christos {
    312  1.1.1.3  christos   sim_fpu op1;
    313  1.1.1.3  christos   sim_fpu op2;
    314  1.1.1.3  christos 
    315  1.1.1.3  christos   sim_fpu_32to (&op1, x);
    316  1.1.1.3  christos   sim_fpu_32to (&op2, y);
    317  1.1.1.3  christos   return sim_fpu_is_nan (&op1) || sim_fpu_is_nan (&op2);
    318  1.1.1.3  christos }
    319  1.1.1.3  christos 
    320  1.1.1.3  christos 
    321      1.1  christos static DF
    322      1.1  christos fextsfdf (CGEN_FPU* fpu, int how UNUSED, SF x)
    323      1.1  christos {
    324      1.1  christos   sim_fpu op1;
    325  1.1.1.4  christos   uint64_t res;
    326      1.1  christos 
    327      1.1  christos   sim_fpu_32to (&op1, x);
    328      1.1  christos   sim_fpu_to64 (&res, &op1);
    329      1.1  christos 
    330      1.1  christos   return res;
    331      1.1  christos }
    332      1.1  christos 
    333      1.1  christos static SF
    334      1.1  christos ftruncdfsf (CGEN_FPU* fpu, int how UNUSED, DF x)
    335      1.1  christos {
    336      1.1  christos   sim_fpu op1;
    337  1.1.1.4  christos   uint32_t res;
    338      1.1  christos 
    339      1.1  christos   sim_fpu_64to (&op1, x);
    340      1.1  christos   sim_fpu_to32 (&res, &op1);
    341      1.1  christos 
    342      1.1  christos   return res;
    343      1.1  christos }
    344      1.1  christos 
    345      1.1  christos static SF
    346      1.1  christos floatsisf (CGEN_FPU* fpu, int how UNUSED, SI x)
    347      1.1  christos {
    348      1.1  christos   sim_fpu ans;
    349  1.1.1.4  christos   uint32_t res;
    350      1.1  christos 
    351      1.1  christos   sim_fpu_i32to (&ans, x, sim_fpu_round_near);
    352      1.1  christos   sim_fpu_to32 (&res, &ans);
    353      1.1  christos   return res;
    354      1.1  christos }
    355      1.1  christos 
    356      1.1  christos static DF
    357      1.1  christos floatsidf (CGEN_FPU* fpu, int how UNUSED, SI x)
    358      1.1  christos {
    359      1.1  christos   sim_fpu ans;
    360  1.1.1.4  christos   uint64_t res;
    361      1.1  christos 
    362      1.1  christos   sim_fpu_i32to (&ans, x, sim_fpu_round_near);
    363      1.1  christos   sim_fpu_to64 (&res, &ans);
    364      1.1  christos   return res;
    365      1.1  christos }
    366      1.1  christos 
    367  1.1.1.3  christos static DF
    368  1.1.1.3  christos floatdidf (CGEN_FPU* fpu, int how UNUSED, DI x)
    369  1.1.1.3  christos {
    370  1.1.1.3  christos   sim_fpu ans;
    371  1.1.1.4  christos   uint64_t res;
    372  1.1.1.3  christos 
    373  1.1.1.3  christos   sim_fpu_i64to (&ans, x, sim_fpu_round_near);
    374  1.1.1.3  christos   sim_fpu_to64 (&res, &ans);
    375  1.1.1.3  christos   return res;
    376  1.1.1.3  christos }
    377  1.1.1.3  christos 
    378      1.1  christos static SF
    379      1.1  christos ufloatsisf (CGEN_FPU* fpu, int how UNUSED, USI x)
    380      1.1  christos {
    381      1.1  christos   sim_fpu ans;
    382  1.1.1.4  christos   uint32_t res;
    383      1.1  christos 
    384      1.1  christos   sim_fpu_u32to (&ans, x, sim_fpu_round_near);
    385      1.1  christos   sim_fpu_to32 (&res, &ans);
    386      1.1  christos   return res;
    387      1.1  christos }
    388      1.1  christos 
    389      1.1  christos static SI
    390      1.1  christos fixsfsi (CGEN_FPU* fpu, int how UNUSED, SF x)
    391      1.1  christos {
    392      1.1  christos   sim_fpu op1;
    393  1.1.1.4  christos   int32_t res;
    394      1.1  christos 
    395      1.1  christos   sim_fpu_32to (&op1, x);
    396      1.1  christos   sim_fpu_to32i (&res, &op1, sim_fpu_round_near);
    397      1.1  christos   return res;
    398      1.1  christos }
    399      1.1  christos 
    400      1.1  christos static SI
    401      1.1  christos fixdfsi (CGEN_FPU* fpu, int how UNUSED, DF x)
    402      1.1  christos {
    403      1.1  christos   sim_fpu op1;
    404  1.1.1.4  christos   int32_t res;
    405      1.1  christos 
    406      1.1  christos   sim_fpu_64to (&op1, x);
    407      1.1  christos   sim_fpu_to32i (&res, &op1, sim_fpu_round_near);
    408      1.1  christos   return res;
    409      1.1  christos }
    410      1.1  christos 
    411  1.1.1.3  christos static DI
    412  1.1.1.3  christos fixdfdi (CGEN_FPU* fpu, int how UNUSED, DF x)
    413  1.1.1.3  christos {
    414  1.1.1.3  christos   sim_fpu op1;
    415  1.1.1.4  christos   int64_t res;
    416  1.1.1.3  christos 
    417  1.1.1.3  christos   sim_fpu_64to (&op1, x);
    418  1.1.1.3  christos   sim_fpu_to64i (&res, &op1, sim_fpu_round_near);
    419  1.1.1.3  christos   return res;
    420  1.1.1.3  christos }
    421  1.1.1.3  christos 
    422      1.1  christos static USI
    423      1.1  christos ufixsfsi (CGEN_FPU* fpu, int how UNUSED, SF x)
    424      1.1  christos {
    425      1.1  christos   sim_fpu op1;
    426  1.1.1.4  christos   uint32_t res;
    427      1.1  christos 
    428      1.1  christos   sim_fpu_32to (&op1, x);
    429      1.1  christos   sim_fpu_to32u (&res, &op1, sim_fpu_round_near);
    430      1.1  christos   return res;
    431      1.1  christos }
    432      1.1  christos 
    433      1.1  christos /* DF mode support */
    435      1.1  christos 
    436      1.1  christos static DF
    437      1.1  christos adddf (CGEN_FPU* fpu, DF x, DF y)
    438      1.1  christos {
    439      1.1  christos   sim_fpu op1;
    440      1.1  christos   sim_fpu op2;
    441  1.1.1.4  christos   sim_fpu ans;
    442      1.1  christos   uint64_t res;
    443      1.1  christos   sim_fpu_status status;
    444      1.1  christos 
    445      1.1  christos   sim_fpu_64to (&op1, x);
    446      1.1  christos   sim_fpu_64to (&op2, y);
    447      1.1  christos   status = sim_fpu_add (&ans, &op1, &op2);
    448      1.1  christos   if (status != 0)
    449      1.1  christos     (*fpu->ops->error) (fpu, status);
    450      1.1  christos   sim_fpu_to64 (&res, &ans);
    451      1.1  christos 
    452      1.1  christos   return res;
    453      1.1  christos }
    454      1.1  christos 
    455      1.1  christos static DF
    456      1.1  christos subdf (CGEN_FPU* fpu, DF x, DF y)
    457      1.1  christos {
    458      1.1  christos   sim_fpu op1;
    459      1.1  christos   sim_fpu op2;
    460  1.1.1.4  christos   sim_fpu ans;
    461      1.1  christos   uint64_t res;
    462      1.1  christos   sim_fpu_status status;
    463      1.1  christos 
    464      1.1  christos   sim_fpu_64to (&op1, x);
    465      1.1  christos   sim_fpu_64to (&op2, y);
    466      1.1  christos   status = sim_fpu_sub (&ans, &op1, &op2);
    467      1.1  christos   if (status != 0)
    468      1.1  christos     (*fpu->ops->error) (fpu, status);
    469      1.1  christos   sim_fpu_to64 (&res, &ans);
    470      1.1  christos 
    471      1.1  christos   return res;
    472      1.1  christos }
    473      1.1  christos 
    474      1.1  christos static DF
    475      1.1  christos muldf (CGEN_FPU* fpu, DF x, DF y)
    476      1.1  christos {
    477      1.1  christos   sim_fpu op1;
    478      1.1  christos   sim_fpu op2;
    479  1.1.1.4  christos   sim_fpu ans;
    480      1.1  christos   uint64_t res;
    481      1.1  christos   sim_fpu_status status;
    482      1.1  christos 
    483      1.1  christos   sim_fpu_64to (&op1, x);
    484      1.1  christos   sim_fpu_64to (&op2, y);
    485      1.1  christos   status = sim_fpu_mul (&ans, &op1, &op2);
    486      1.1  christos   if (status != 0)
    487      1.1  christos     (*fpu->ops->error) (fpu, status);
    488      1.1  christos   sim_fpu_to64 (&res, &ans);
    489      1.1  christos 
    490      1.1  christos   return res;
    491      1.1  christos }
    492      1.1  christos 
    493      1.1  christos static DF
    494      1.1  christos divdf (CGEN_FPU* fpu, DF x, DF y)
    495      1.1  christos {
    496      1.1  christos   sim_fpu op1;
    497      1.1  christos   sim_fpu op2;
    498  1.1.1.4  christos   sim_fpu ans;
    499      1.1  christos   uint64_t res;
    500      1.1  christos   sim_fpu_status status;
    501      1.1  christos 
    502      1.1  christos   sim_fpu_64to (&op1, x);
    503      1.1  christos   sim_fpu_64to (&op2, y);
    504      1.1  christos   status = sim_fpu_div (&ans, &op1, &op2);
    505      1.1  christos   if (status != 0)
    506      1.1  christos     (*fpu->ops->error) (fpu, status);
    507      1.1  christos   sim_fpu_to64 (&res, &ans);
    508      1.1  christos 
    509      1.1  christos   return res;
    510      1.1  christos }
    511      1.1  christos 
    512  1.1.1.2  christos static DF
    513  1.1.1.2  christos remdf (CGEN_FPU* fpu, DF x, DF y)
    514  1.1.1.2  christos {
    515  1.1.1.2  christos   sim_fpu op1;
    516  1.1.1.2  christos   sim_fpu op2;
    517  1.1.1.4  christos   sim_fpu ans;
    518  1.1.1.2  christos   uint64_t res;
    519  1.1.1.2  christos   sim_fpu_status status;
    520  1.1.1.2  christos 
    521  1.1.1.2  christos   sim_fpu_64to (&op1, x);
    522  1.1.1.2  christos   sim_fpu_64to (&op2, y);
    523  1.1.1.2  christos   status = sim_fpu_rem (&ans, &op1, &op2);
    524  1.1.1.2  christos   if (status != 0)
    525  1.1.1.2  christos     (*fpu->ops->error) (fpu, status);
    526  1.1.1.2  christos   sim_fpu_to64(&res, &ans);
    527  1.1.1.2  christos 
    528  1.1.1.2  christos   return res;
    529  1.1.1.2  christos }
    530  1.1.1.2  christos 
    531      1.1  christos static DF
    532      1.1  christos negdf (CGEN_FPU* fpu, DF x)
    533      1.1  christos {
    534      1.1  christos   sim_fpu op1;
    535  1.1.1.4  christos   sim_fpu ans;
    536      1.1  christos   uint64_t res;
    537      1.1  christos   sim_fpu_status status;
    538      1.1  christos 
    539      1.1  christos   sim_fpu_64to (&op1, x);
    540      1.1  christos   status = sim_fpu_neg (&ans, &op1);
    541      1.1  christos   if (status != 0)
    542      1.1  christos     (*fpu->ops->error) (fpu, status);
    543      1.1  christos   sim_fpu_to64 (&res, &ans);
    544      1.1  christos 
    545      1.1  christos   return res;
    546      1.1  christos }
    547      1.1  christos 
    548      1.1  christos static DF
    549      1.1  christos absdf (CGEN_FPU* fpu, DF x)
    550      1.1  christos {
    551      1.1  christos   sim_fpu op1;
    552  1.1.1.4  christos   sim_fpu ans;
    553      1.1  christos   uint64_t res;
    554      1.1  christos   sim_fpu_status status;
    555      1.1  christos 
    556      1.1  christos   sim_fpu_64to (&op1, x);
    557      1.1  christos   status = sim_fpu_abs (&ans, &op1);
    558      1.1  christos   if (status != 0)
    559      1.1  christos     (*fpu->ops->error) (fpu, status);
    560      1.1  christos   sim_fpu_to64 (&res, &ans);
    561      1.1  christos 
    562      1.1  christos   return res;
    563      1.1  christos }
    564      1.1  christos 
    565      1.1  christos static DF
    566      1.1  christos sqrtdf (CGEN_FPU* fpu, DF x)
    567      1.1  christos {
    568      1.1  christos   sim_fpu op1;
    569  1.1.1.4  christos   sim_fpu ans;
    570      1.1  christos   uint64_t res;
    571      1.1  christos   sim_fpu_status status;
    572      1.1  christos 
    573      1.1  christos   sim_fpu_64to (&op1, x);
    574      1.1  christos   status = sim_fpu_sqrt (&ans, &op1);
    575      1.1  christos   if (status != 0)
    576      1.1  christos     (*fpu->ops->error) (fpu, status);
    577      1.1  christos   sim_fpu_to64 (&res, &ans);
    578      1.1  christos 
    579      1.1  christos   return res;
    580      1.1  christos }
    581      1.1  christos 
    582      1.1  christos static DF
    583      1.1  christos invdf (CGEN_FPU* fpu, DF x)
    584      1.1  christos {
    585      1.1  christos   sim_fpu op1;
    586  1.1.1.4  christos   sim_fpu ans;
    587      1.1  christos   uint64_t res;
    588      1.1  christos   sim_fpu_status status;
    589      1.1  christos 
    590      1.1  christos   sim_fpu_64to (&op1, x);
    591      1.1  christos   status = sim_fpu_inv (&ans, &op1);
    592      1.1  christos   if (status != 0)
    593      1.1  christos     (*fpu->ops->error) (fpu, status);
    594      1.1  christos   sim_fpu_to64 (&res, &ans);
    595      1.1  christos 
    596      1.1  christos   return res;
    597      1.1  christos }
    598      1.1  christos 
    599      1.1  christos static DF
    600      1.1  christos mindf (CGEN_FPU* fpu, DF x, DF y)
    601      1.1  christos {
    602      1.1  christos   sim_fpu op1;
    603      1.1  christos   sim_fpu op2;
    604  1.1.1.4  christos   sim_fpu ans;
    605      1.1  christos   uint64_t res;
    606      1.1  christos   sim_fpu_status status;
    607      1.1  christos 
    608      1.1  christos   sim_fpu_64to (&op1, x);
    609      1.1  christos   sim_fpu_64to (&op2, y);
    610      1.1  christos   status = sim_fpu_min (&ans, &op1, &op2);
    611      1.1  christos   if (status != 0)
    612      1.1  christos     (*fpu->ops->error) (fpu, status);
    613      1.1  christos   sim_fpu_to64 (&res, &ans);
    614      1.1  christos 
    615      1.1  christos   return res;
    616      1.1  christos }
    617      1.1  christos 
    618      1.1  christos static DF
    619      1.1  christos maxdf (CGEN_FPU* fpu, DF x, DF y)
    620      1.1  christos {
    621      1.1  christos   sim_fpu op1;
    622      1.1  christos   sim_fpu op2;
    623  1.1.1.4  christos   sim_fpu ans;
    624      1.1  christos   uint64_t res;
    625      1.1  christos   sim_fpu_status status;
    626      1.1  christos 
    627      1.1  christos   sim_fpu_64to (&op1, x);
    628      1.1  christos   sim_fpu_64to (&op2, y);
    629      1.1  christos   status = sim_fpu_max (&ans, &op1, &op2);
    630      1.1  christos   if (status != 0)
    631      1.1  christos     (*fpu->ops->error) (fpu, status);
    632      1.1  christos   sim_fpu_to64 (&res, &ans);
    633      1.1  christos 
    634      1.1  christos   return res;
    635      1.1  christos }
    636      1.1  christos 
    637      1.1  christos static CGEN_FP_CMP
    638      1.1  christos cmpdf (CGEN_FPU* fpu, DF x, DF y)
    639      1.1  christos {
    640      1.1  christos   sim_fpu op1;
    641      1.1  christos   sim_fpu op2;
    642      1.1  christos 
    643      1.1  christos   sim_fpu_64to (&op1, x);
    644      1.1  christos   sim_fpu_64to (&op2, y);
    645      1.1  christos 
    646      1.1  christos   if (sim_fpu_is_nan (&op1)
    647      1.1  christos       || sim_fpu_is_nan (&op2))
    648      1.1  christos     return FP_CMP_NAN;
    649      1.1  christos 
    650      1.1  christos   if (x < y)
    651      1.1  christos     return FP_CMP_LT;
    652      1.1  christos   if (x > y)
    653      1.1  christos     return FP_CMP_GT;
    654      1.1  christos   return FP_CMP_EQ;
    655      1.1  christos }
    656      1.1  christos 
    657      1.1  christos static int
    658      1.1  christos eqdf (CGEN_FPU* fpu, DF x, DF y)
    659      1.1  christos {
    660      1.1  christos   sim_fpu op1;
    661      1.1  christos   sim_fpu op2;
    662      1.1  christos 
    663      1.1  christos   sim_fpu_64to (&op1, x);
    664      1.1  christos   sim_fpu_64to (&op2, y);
    665      1.1  christos   return sim_fpu_is_eq (&op1, &op2);
    666      1.1  christos }
    667      1.1  christos 
    668      1.1  christos static int
    669      1.1  christos nedf (CGEN_FPU* fpu, DF x, DF y)
    670      1.1  christos {
    671      1.1  christos   sim_fpu op1;
    672      1.1  christos   sim_fpu op2;
    673      1.1  christos 
    674      1.1  christos   sim_fpu_64to (&op1, x);
    675      1.1  christos   sim_fpu_64to (&op2, y);
    676      1.1  christos   return sim_fpu_is_ne (&op1, &op2);
    677      1.1  christos }
    678      1.1  christos 
    679      1.1  christos static int
    680      1.1  christos ltdf (CGEN_FPU* fpu, DF x, DF y)
    681      1.1  christos {
    682      1.1  christos   sim_fpu op1;
    683      1.1  christos   sim_fpu op2;
    684      1.1  christos 
    685      1.1  christos   sim_fpu_64to (&op1, x);
    686      1.1  christos   sim_fpu_64to (&op2, y);
    687      1.1  christos   return sim_fpu_is_lt (&op1, &op2);
    688      1.1  christos }
    689      1.1  christos 
    690      1.1  christos static int
    691      1.1  christos ledf (CGEN_FPU* fpu, DF x, DF y)
    692      1.1  christos {
    693      1.1  christos   sim_fpu op1;
    694      1.1  christos   sim_fpu op2;
    695      1.1  christos 
    696      1.1  christos   sim_fpu_64to (&op1, x);
    697      1.1  christos   sim_fpu_64to (&op2, y);
    698      1.1  christos   return sim_fpu_is_le (&op1, &op2);
    699      1.1  christos }
    700      1.1  christos 
    701      1.1  christos static int
    702      1.1  christos gtdf (CGEN_FPU* fpu, DF x, DF y)
    703      1.1  christos {
    704      1.1  christos   sim_fpu op1;
    705      1.1  christos   sim_fpu op2;
    706      1.1  christos 
    707      1.1  christos   sim_fpu_64to (&op1, x);
    708      1.1  christos   sim_fpu_64to (&op2, y);
    709      1.1  christos   return sim_fpu_is_gt (&op1, &op2);
    710      1.1  christos }
    711      1.1  christos 
    712      1.1  christos static int
    713      1.1  christos gedf (CGEN_FPU* fpu, DF x, DF y)
    714      1.1  christos {
    715      1.1  christos   sim_fpu op1;
    716      1.1  christos   sim_fpu op2;
    717      1.1  christos 
    718      1.1  christos   sim_fpu_64to (&op1, x);
    719      1.1  christos   sim_fpu_64to (&op2, y);
    720      1.1  christos   return sim_fpu_is_ge (&op1, &op2);
    721  1.1.1.3  christos }
    722  1.1.1.3  christos 
    723  1.1.1.3  christos static int
    724  1.1.1.3  christos unordereddf (CGEN_FPU* fpu, DF x, DF y)
    725  1.1.1.3  christos {
    726  1.1.1.3  christos   sim_fpu op1;
    727  1.1.1.3  christos   sim_fpu op2;
    728  1.1.1.3  christos 
    729  1.1.1.3  christos   sim_fpu_64to (&op1, x);
    730  1.1.1.3  christos   sim_fpu_64to (&op2, y);
    731  1.1.1.3  christos   return sim_fpu_is_nan (&op1) || sim_fpu_is_nan (&op2);
    732      1.1  christos }
    733      1.1  christos 
    734      1.1  christos /* Initialize FP_OPS to use accurate library.  */
    736      1.1  christos 
    737      1.1  christos void
    738      1.1  christos cgen_init_accurate_fpu (SIM_CPU* cpu, CGEN_FPU* fpu, CGEN_FPU_ERROR_FN* error)
    739      1.1  christos {
    740      1.1  christos   CGEN_FP_OPS* o;
    741      1.1  christos 
    742      1.1  christos   fpu->owner = cpu;
    743      1.1  christos   /* ??? small memory leak, not freed by sim_close */
    744      1.1  christos   fpu->ops = (CGEN_FP_OPS*) xmalloc (sizeof (CGEN_FP_OPS));
    745      1.1  christos 
    746      1.1  christos   o = fpu->ops;
    747      1.1  christos   memset (o, 0, sizeof (*o));
    748      1.1  christos 
    749      1.1  christos   o->error = error;
    750      1.1  christos 
    751      1.1  christos   o->addsf = addsf;
    752      1.1  christos   o->subsf = subsf;
    753  1.1.1.2  christos   o->mulsf = mulsf;
    754      1.1  christos   o->divsf = divsf;
    755      1.1  christos   o->remsf = remsf;
    756      1.1  christos   o->negsf = negsf;
    757      1.1  christos   o->abssf = abssf;
    758      1.1  christos   o->sqrtsf = sqrtsf;
    759      1.1  christos   o->invsf = invsf;
    760      1.1  christos   o->minsf = minsf;
    761      1.1  christos   o->maxsf = maxsf;
    762      1.1  christos   o->cmpsf = cmpsf;
    763      1.1  christos   o->eqsf = eqsf;
    764      1.1  christos   o->nesf = nesf;
    765      1.1  christos   o->ltsf = ltsf;
    766      1.1  christos   o->lesf = lesf;
    767  1.1.1.3  christos   o->gtsf = gtsf;
    768      1.1  christos   o->gesf = gesf;
    769      1.1  christos   o->unorderedsf = unorderedsf;
    770      1.1  christos 
    771      1.1  christos   o->adddf = adddf;
    772      1.1  christos   o->subdf = subdf;
    773  1.1.1.2  christos   o->muldf = muldf;
    774      1.1  christos   o->divdf = divdf;
    775      1.1  christos   o->remdf = remdf;
    776      1.1  christos   o->negdf = negdf;
    777      1.1  christos   o->absdf = absdf;
    778      1.1  christos   o->sqrtdf = sqrtdf;
    779      1.1  christos   o->invdf = invdf;
    780      1.1  christos   o->mindf = mindf;
    781      1.1  christos   o->maxdf = maxdf;
    782      1.1  christos   o->cmpdf = cmpdf;
    783      1.1  christos   o->eqdf = eqdf;
    784      1.1  christos   o->nedf = nedf;
    785      1.1  christos   o->ltdf = ltdf;
    786      1.1  christos   o->ledf = ledf;
    787  1.1.1.3  christos   o->gtdf = gtdf;
    788      1.1  christos   o->gedf = gedf;
    789      1.1  christos   o->unordereddf = unordereddf;
    790      1.1  christos   o->fextsfdf = fextsfdf;
    791      1.1  christos   o->ftruncdfsf = ftruncdfsf;
    792  1.1.1.3  christos   o->floatsisf = floatsisf;
    793      1.1  christos   o->floatsidf = floatsidf;
    794      1.1  christos   o->floatdidf = floatdidf;
    795      1.1  christos   o->ufloatsisf = ufloatsisf;
    796  1.1.1.3  christos   o->fixsfsi = fixsfsi;
    797      1.1  christos   o->fixdfsi = fixdfsi;
    798      1.1  christos   o->fixdfdi = fixdfdi;
    799                      o->ufixsfsi = ufixsfsi;
    800                    }
    801