Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/app/tester/float/softfloat1.c

    r3e6a98c5 rc0c38c7c  
    2929#include <stdio.h>
    3030#include <stdlib.h>
    31 #include <sftypes.h>
     31#include <mathtypes.h>
    3232#include <add.h>
    3333#include <sub.h>
     
    3939#include "../tester.h"
    4040
    41 #define OPERANDS  10
    42 #define PRECISION  10000
     41#define add_float  __addsf3
     42#define sub_float  __subsf3
     43#define mul_float  __mulsf3
     44#define div_float  __divsf3
     45
     46#define is_float_lt  __ltsf2
     47#define is_float_gt  __gtsf2
     48#define is_float_eq  __eqsf2
     49
     50#define add_double  __adddf3
     51#define sub_double  __subdf3
     52#define mul_double  __muldf3
     53#define div_double  __divdf3
     54
     55#define is_double_lt  __ltdf2
     56#define is_double_gt  __gtdf2
     57#define is_double_eq  __eqdf2
     58
     59#define uint_to_double  __floatsidf
     60#define double_to_uint  __fixunsdfsi
     61#define double_to_int   __fixdfsi
     62
     63#define OPERANDS   10
     64#define PRECISION  1000
    4365
    4466#define PRIdCMPTYPE  PRId32
     
    4668typedef int32_t cmptype_t;
    4769
    48 typedef void (* uint_to_double_op_t)(unsigned int, double *, double_t *);
     70typedef void (* uint_to_double_op_t)(unsigned int, double *, double *);
    4971typedef void (* double_to_uint_op_t)(double, unsigned int *, unsigned int *);
    50 typedef void (* float_binary_op_t)(float, float, float *, float_t *);
    51 typedef void (* double_binary_op_t)(double, double, double *, double_t *);
     72typedef void (* float_binary_op_t)(float, float, float *, float *);
     73typedef void (* float_cmp_op_t)(float, float, cmptype_t *, cmptype_t *);
     74typedef void (* double_binary_op_t)(double, double, double *, double *);
    5275typedef void (* double_cmp_op_t)(double, double, cmptype_t *, cmptype_t *);
    5376
     
    5679    cmptype_t *);
    5780
    58 #define NUMBERS \
     81#define NUMBERS \
    5982        3.5, -2.1, 100.0, 50.0, -1024.0, 0.0, 768.3156, 1080.499999, -600.0, 1.0
    6083
     
    6386};
    6487
    65 static double dop_a[OPERANDS] = {
     88static double dop_a[OPERANDS] = {
    6689        NUMBERS
    6790};
    6891
    6992static unsigned int uop_a[OPERANDS] = {
    70         4, -100, 100, 50, 1024, 0, 1000000, -1U, 0x80000000U, 500
     93        4, 2, 100, 50, 1024, 0, 1000000, 1, 0x8000000, 500
    7194};
    7295
    73 static cmptype_t cmpabs(cmptype_t a)
    74 {
    75         if (a >= 0)
    76                 return a;
    77        
    78         return -a;
    79 }
    80 
    81 static int dcmp(double a, double b)
     96static int fcmp(float a, float b)
    8297{
    8398        if (a < b)
    8499                return -1;
    85         else if (a > b)
     100       
     101        if (a > b)
    86102                return 1;
    87 
     103       
    88104        return 0;
    89105}
    90106
    91 static void
    92 uint_to_double_template(void *f, unsigned i, cmptype_t *pic, cmptype_t *pisc)
    93 {
     107static int dcmp(double a, double b)
     108{
     109        if (a < b)
     110                return -1;
     111       
     112        if (a > b)
     113                return 1;
     114       
     115        return 0;
     116}
     117
     118static void uint_to_double_template(void *f, unsigned i, cmptype_t *pic,
     119    cmptype_t *pisc)
     120{
     121        uint_to_double_op_t op = (uint_to_double_op_t) f;
     122       
    94123        double c;
    95         double_t sc;
    96 
    97         uint_to_double_op_t op = (uint_to_double_op_t) f;
    98        
     124        double sc;
    99125        op(uop_a[i], &c, &sc);
    100 
     126       
    101127        *pic = (cmptype_t) (c * PRECISION);
    102         *pisc = (cmptype_t) (sc.val * PRECISION);
    103 }
    104 
    105 static void
    106 double_to_uint_template(void *f, unsigned i, cmptype_t *pic, cmptype_t *pisc)
    107 {
     128        *pisc = (cmptype_t) (sc * PRECISION);
     129}
     130
     131static void double_to_uint_template(void *f, unsigned i, cmptype_t *pic,
     132    cmptype_t *pisc)
     133{
     134        double_to_uint_op_t op = (double_to_uint_op_t) f;
     135       
    108136        unsigned int c;
    109137        unsigned int sc;
    110 
    111         double_to_uint_op_t op = (double_to_uint_op_t) f;
    112        
    113138        op(dop_a[i], &c, &sc);
    114 
     139       
    115140        *pic = (cmptype_t) c;
    116141        *pisc = (cmptype_t) sc;
    117142}
    118143
    119 
    120 static void
    121 float_template_binary(void *f, unsigned i, unsigned j, cmptype_t *pic,
    122     cmptype_t *pisc)
    123 {
     144static void float_template_binary(void *f, unsigned i, unsigned j,
     145    cmptype_t *pic, cmptype_t *pisc)
     146{
     147        float_binary_op_t op = (float_binary_op_t) f;
     148       
    124149        float c;
    125         float_t sc;
    126 
    127         float_binary_op_t op = (float_binary_op_t) f;
    128        
     150        float sc;
    129151        op(fop_a[i], fop_a[j], &c, &sc);
    130 
     152       
    131153        *pic = (cmptype_t) (c * PRECISION);
    132         *pisc = (cmptype_t) (sc.val * PRECISION);
    133 }
    134 
    135 static void
    136 double_template_binary(void *f, unsigned i, unsigned j, cmptype_t *pic,
    137     cmptype_t *pisc)
    138 {
     154        *pisc = (cmptype_t) (sc * PRECISION);
     155}
     156
     157static void float_compare_template(void *f, unsigned i, unsigned j,
     158    cmptype_t *pis, cmptype_t *piss)
     159{
     160        float_cmp_op_t op = (float_cmp_op_t) f;
     161       
     162        op(dop_a[i], dop_a[j], pis, piss);
     163}
     164
     165static void double_template_binary(void *f, unsigned i, unsigned j,
     166    cmptype_t *pic, cmptype_t *pisc)
     167{
     168        double_binary_op_t op = (double_binary_op_t) f;
     169       
    139170        double c;
    140         double_t sc;
    141 
    142         double_binary_op_t op = (double_binary_op_t) f;
    143        
     171        double sc;
    144172        op(dop_a[i], dop_a[j], &c, &sc);
    145 
     173       
    146174        *pic = (cmptype_t) (c * PRECISION);
    147         *pisc = (cmptype_t) (sc.val * PRECISION);
    148 }
    149 
    150 static void
    151 double_compare_template(void *f, unsigned i, unsigned j, cmptype_t *pis,
    152     cmptype_t *piss)
     175        *pisc = (cmptype_t) (sc * PRECISION);
     176}
     177
     178static void double_compare_template(void *f, unsigned i, unsigned j,
     179    cmptype_t *pis, cmptype_t *piss)
    153180{
    154181        double_cmp_op_t op = (double_cmp_op_t) f;
     
    164191                cmptype_t ic;
    165192                cmptype_t isc;
    166 
    167                 template(f, i, &ic, &isc);     
    168                 cmptype_t diff = cmpabs(ic - isc);
    169                        
     193               
     194                template(f, i, &ic, &isc);
     195                cmptype_t diff = ic - isc;
     196               
    170197                if (diff != 0) {
    171                         TPRINTF("i=%u diff=%" PRIdCMPTYPE "\n", i, diff);
     198                        TPRINTF("i=%u ic=%" PRIdCMPTYPE " isc=%" PRIdCMPTYPE "\n",
     199                            i, ic, isc);
    172200                        correct = false;
    173201                }
     
    182210       
    183211        for (unsigned int i = 0; i < OPERANDS; i++) {
    184                 for (unsigned int j = 0; j < OPERANDS; j++) {                   
     212                for (unsigned int j = 0; j < OPERANDS; j++) {
    185213                        cmptype_t ic;
    186214                        cmptype_t isc;
    187 
    188                         template(f, i, j, &ic, &isc);   
    189                         cmptype_t diff = cmpabs(ic - isc);
     215                       
     216                        template(f, i, j, &ic, &isc);
     217                        cmptype_t diff = ic - isc;
    190218                       
    191219                        if (diff != 0) {
    192                                 TPRINTF("i=%u, j=%u diff=%" PRIdCMPTYPE "\n",
    193                                     i, j, diff);
     220                                TPRINTF("i=%u, j=%u ic=%" PRIdCMPTYPE
     221                                    " isc=%" PRIdCMPTYPE "\n", i, j, ic, isc);
    194222                                correct = false;
    195223                        }
     
    200228}
    201229
    202 static void uint_to_double_operator(unsigned int a, double *pc, double_t *psc)
     230static void uint_to_double_operator(unsigned int a, double *pc, double *psc)
    203231{
    204232        *pc = (double) a;
    205         psc->data = uint_to_double(a);
    206 }
    207 
    208 static void
    209 double_to_uint_operator(double a, unsigned int *pc, unsigned int *psc)
    210 {
    211         double_t sa;
    212 
    213         sa.val = a;
    214 
     233        *psc = uint_to_double(a);
     234}
     235
     236static void double_to_uint_operator(double a, unsigned int *pc,
     237    unsigned int *psc)
     238{
    215239        *pc = (unsigned int) a;
    216         *psc = double_to_uint(sa.data);
    217 }
    218 
    219 static void
    220 double_to_int_operator(double a, unsigned int *pc, unsigned int *psc)
    221 {
    222         double_t sa;
    223 
    224         sa.val = a;
    225 
     240        *psc = double_to_uint(a);
     241}
     242
     243static void double_to_int_operator(double a, unsigned int *pc,
     244    unsigned int *psc)
     245{
    226246        *pc = (int) a;
    227         *psc = double_to_int(sa.data);
    228 }
    229 
    230 static void float_add_operator(float a, float b, float *pc, float_t *psc)
     247        *psc = double_to_int(a);
     248}
     249
     250static void float_add_operator(float a, float b, float *pc, float *psc)
    231251{
    232252        *pc = a + b;
    233        
    234         float_t sa;
    235         float_t sb;
    236        
    237         sa.val = a;
    238         sb.val = b;
    239         if (sa.data.parts.sign == sb.data.parts.sign)
    240                 psc->data = add_float(sa.data, sb.data);
    241         else if (sa.data.parts.sign) {
    242                 sa.data.parts.sign = 0;
    243                 psc->data = sub_float(sb.data, sa.data);
    244         } else {
    245                 sb.data.parts.sign = 0;
    246                 psc->data = sub_float(sa.data, sb.data);
    247         }
    248 }
    249 
    250 static void float_mul_operator(float a, float b, float *pc, float_t *psc)
     253        *psc = add_float(a, b);
     254}
     255
     256static void float_sub_operator(float a, float b, float *pc, float *psc)
     257{
     258        *pc = a - b;
     259        *psc = sub_float(a, b);
     260}
     261
     262static void float_mul_operator(float a, float b, float *pc, float *psc)
    251263{
    252264        *pc = a * b;
    253        
    254         float_t sa;
    255         float_t sb;
    256        
    257         sa.val = a;
    258         sb.val = b;
    259         psc->data = mul_float(sa.data, sb.data);
    260 }
    261 
    262 static void float_div_operator(float a, float b, float *pc, float_t *psc)
     265        *psc = mul_float(a, b);
     266}
     267
     268static void float_div_operator(float a, float b, float *pc, float *psc)
    263269{
    264270        if ((cmptype_t) b == 0) {
    265271                *pc = 0.0;
    266                 psc->val = 0.0;
     272                *psc = 0.0;
    267273                return;
    268274        }
    269 
     275       
    270276        *pc = a / b;
    271        
    272         float_t sa;
    273         float_t sb;
    274        
    275         sa.val = a;
    276         sb.val = b;
    277         psc->data = div_float(sa.data, sb.data);
    278 }
    279 
    280 static void double_add_operator(double a, double b, double *pc, double_t *psc)
    281 {
    282         *pc = a + b;
    283        
    284         double_t sa;
    285         double_t sb;
    286        
    287         sa.val = a;
    288         sb.val = b;
    289         if (sa.data.parts.sign == sb.data.parts.sign)
    290                 psc->data = add_double(sa.data, sb.data);
    291         else if (sa.data.parts.sign) {
    292                 sa.data.parts.sign = 0;
    293                 psc->data = sub_double(sb.data, sa.data);
    294         } else {
    295                 sb.data.parts.sign = 0;
    296                 psc->data = sub_double(sa.data, sb.data);
    297         }
    298 }
    299 
    300 static void double_mul_operator(double a, double b, double *pc, double_t *psc)
    301 {
    302         *pc = a * b;
    303        
    304         double_t sa;
    305         double_t sb;
    306        
    307         sa.val = a;
    308         sb.val = b;
    309         psc->data = mul_double(sa.data, sb.data);
    310 }
    311 
    312 static void double_div_operator(double a, double b, double *pc, double_t *psc)
    313 {
    314         if ((cmptype_t) b == 0) {
    315                 *pc = 0.0;
    316                 psc->val = 0.0;
    317                 return;
    318         }
    319 
    320         *pc = a / b;
    321        
    322         double_t sa;
    323         double_t sb;
    324        
    325         sa.val = a;
    326         sb.val = b;
    327         psc->data = div_double(sa.data, sb.data);
    328 }
    329 
    330 static void
    331 double_cmp_operator(double a, double b, cmptype_t *pis, cmptype_t *piss)
    332 {
    333         *pis = dcmp(a, b);
    334 
    335         double_t sa;
    336         double_t sb;
    337 
    338         sa.val = a;
    339         sb.val = b;
    340 
    341         if (is_double_lt(sa.data, sb.data))
     277        *psc = div_float(a, b);
     278}
     279
     280static void float_cmp_operator(float a, float b, cmptype_t *pis,
     281    cmptype_t *piss)
     282{
     283        *pis = fcmp(a, b);
     284       
     285        if (is_float_lt(a, b) == -1)
    342286                *piss = -1;
    343         else if (is_double_gt(sa.data, sb.data))
     287        else if (is_float_gt(a, b) == 1)
    344288                *piss = 1;
    345         else if (is_double_eq(sa.data, sb.data))
     289        else if (is_float_eq(a, b) == 0)
    346290                *piss = 0;
    347291        else
     
    349293}
    350294
     295static void double_add_operator(double a, double b, double *pc, double *psc)
     296{
     297        *pc = a + b;
     298        *psc = add_double(a, b);
     299}
     300
     301static void double_sub_operator(double a, double b, double *pc, double *psc)
     302{
     303        *pc = a - b;
     304        *psc = sub_double(a, b);
     305}
     306
     307static void double_mul_operator(double a, double b, double *pc, double *psc)
     308{
     309        *pc = a * b;
     310        *psc = mul_double(a, b);
     311}
     312
     313static void double_div_operator(double a, double b, double *pc, double *psc)
     314{
     315        if ((cmptype_t) b == 0) {
     316                *pc = 0.0;
     317                *psc = 0.0;
     318                return;
     319        }
     320       
     321        *pc = a / b;
     322        *psc = div_double(a, b);
     323}
     324
     325static void double_cmp_operator(double a, double b, cmptype_t *pis,
     326    cmptype_t *piss)
     327{
     328        *pis = dcmp(a, b);
     329       
     330        if (is_double_lt(a, b) == -1)
     331                *piss = -1;
     332        else if (is_double_gt(a, b) == 1)
     333                *piss = 1;
     334        else if (is_double_eq(a, b) == 0)
     335                *piss = 0;
     336        else
     337                *piss = 42;
     338}
     339
    351340const char *test_softfloat1(void)
    352341{
    353         const char *err = NULL;
    354 
     342        bool err = false;
     343       
    355344        if (!test_template_binary(float_template_binary, float_add_operator)) {
    356                 err = "Float addition failed";
    357                 TPRINTF("%s\n", err);
    358         }
     345                err = true;
     346                TPRINTF("%s\n", "Float addition failed");
     347        }
     348       
     349        if (!test_template_binary(float_template_binary, float_sub_operator)) {
     350                err = true;
     351                TPRINTF("%s\n", "Float addition failed");
     352        }
     353       
    359354        if (!test_template_binary(float_template_binary, float_mul_operator)) {
    360                 err = "Float multiplication failed";
    361                 TPRINTF("%s\n", err);
    362         }
     355                err = true;
     356                TPRINTF("%s\n", "Float multiplication failed");
     357        }
     358       
    363359        if (!test_template_binary(float_template_binary, float_div_operator)) {
    364                 err = "Float division failed";
    365                 TPRINTF("%s\n", err);
    366         }
     360                err = true;
     361                TPRINTF("%s\n", "Float division failed");
     362        }
     363       
     364        if (!test_template_binary(float_compare_template, float_cmp_operator)) {
     365                err = true;
     366                TPRINTF("%s\n", "Float comparison failed");
     367        }
     368       
    367369        if (!test_template_binary(double_template_binary, double_add_operator)) {
    368                 err = "Double addition failed";
    369                 TPRINTF("%s\n", err);
    370         }
     370                err = true;
     371                TPRINTF("%s\n", "Double addition failed");
     372        }
     373       
     374        if (!test_template_binary(double_template_binary, double_sub_operator)) {
     375                err = true;
     376                TPRINTF("%s\n", "Double addition failed");
     377        }
     378       
    371379        if (!test_template_binary(double_template_binary, double_mul_operator)) {
    372                 err = "Double multiplication failed";
    373                 TPRINTF("%s\n", err);
    374         }
     380                err = true;
     381                TPRINTF("%s\n", "Double multiplication failed");
     382        }
     383       
    375384        if (!test_template_binary(double_template_binary, double_div_operator)) {
    376                 err = "Double division failed";
    377                 TPRINTF("%s\n", err);
    378         }
     385                err = true;
     386                TPRINTF("%s\n", "Double division failed");
     387        }
     388       
    379389        if (!test_template_binary(double_compare_template, double_cmp_operator)) {
    380                 err = "Double comparison failed";
    381                 TPRINTF("%s\n", err);
    382         }
     390                err = true;
     391                TPRINTF("%s\n", "Double comparison failed");
     392        }
     393       
    383394        if (!test_template_unary(uint_to_double_template,
    384395            uint_to_double_operator)) {
    385                 err = "Conversion from unsigned int to double failed";
    386                 TPRINTF("%s\n", err);
    387         }
     396                err = true;
     397                TPRINTF("%s\n", "Conversion from unsigned int to double failed");
     398        }
     399       
    388400        if (!test_template_unary(double_to_uint_template,
    389401            double_to_uint_operator)) {
    390                 err = "Conversion from double to unsigned int failed";
    391                 TPRINTF("%s\n", err);
    392         }
     402                err = true;
     403                TPRINTF("%s\n", "Conversion from double to unsigned int failed");
     404        }
     405       
    393406        if (!test_template_unary(double_to_uint_template,
    394407            double_to_int_operator)) {
    395                 err = "Conversion from double to signed int failed";
    396                 TPRINTF("%s\n", err);
    397         }
    398        
    399         return err;
    400 }
    401 
     408                err = true;
     409                TPRINTF("%s\n", "Conversion from double to signed int failed");
     410        }
     411       
     412        if (err)
     413                return "Software floating point imprecision";
     414       
     415        return NULL;
     416}
Note: See TracChangeset for help on using the changeset viewer.