Changeset 58775d30 in mainline for uspace/lib


Ignore:
Timestamp:
2015-03-16T16:07:21Z (11 years ago)
Author:
Jan Vesely <jano.vesely@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
2003739
Parents:
6069061 (diff), 795e2bf (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Mainline changes

Location:
uspace/lib
Files:
8 added
3 deleted
56 edited

Legend:

Unmodified
Added
Removed
  • uspace/lib/c/Makefile

    r6069061 r58775d30  
    4747LSONAME = libc.so0
    4848
     49LIBS = $(LIBURCU_PREFIX)/liburcu.a
     50EXTRA_CFLAGS += -I$(LIBURCU_PREFIX)
     51
    4952-include $(CONFIG_MAKEFILE)
    5053-include arch/$(UARCH)/Makefile.inc
     
    8891        generic/pcb.c \
    8992        generic/smc.c \
     93        generic/smp_memory_barrier.c \
    9094        generic/thread.c \
    9195        generic/tls.c \
  • uspace/lib/c/arch/ia32/Makefile.common

    r6069061 r58775d30  
    3232        GCC_CFLAGS += -march=pentium -fno-omit-frame-pointer
    3333endif
     34
    3435CLANG_CFLAGS += -fno-omit-frame-pointer
    3536
  • uspace/lib/c/arch/ia64/include/libarch/types.h

    r6069061 r58775d30  
    4646#define SSIZE_MAX  INT64_MAX
    4747
    48 typedef struct {
    49         uint64_t lo;
    50         int64_t hi;
    51 } __attribute__((aligned(16))) int128_t;
    52 
    53 typedef struct {
    54         uint64_t lo;
    55         uint64_t hi;
    56 } __attribute__((aligned(16))) uint128_t;
    57 
    5848typedef uint64_t sysarg_t;
    5949typedef int64_t native_t;
  • uspace/lib/c/generic/adt/hash_table.c

    r6069061 r58775d30  
    134134        free(h->bucket);
    135135
    136         h->bucket = 0;
     136        h->bucket = NULL;
    137137        h->bucket_cnt = 0;
    138138}
  • uspace/lib/c/generic/async.c

    r6069061 r58775d30  
    167167
    168168/** Async framework global futex */
    169 atomic_t async_futex = FUTEX_INITIALIZER;
     169futex_t async_futex = FUTEX_INITIALIZER;
    170170
    171171/** Number of threads waiting for IPC in the kernel. */
     
    820820        if (usecs) {
    821821                getuptime(&conn->wdata.to_event.expires);
    822                 tv_add(&conn->wdata.to_event.expires, usecs);
     822                tv_add_diff(&conn->wdata.to_event.expires, usecs);
    823823        } else
    824824                conn->wdata.to_event.inlist = false;
     
    12141214
    12151215                        } else {
    1216                                 timeout = tv_sub(&waiter->to_event.expires, &tv);
     1216                                timeout = tv_sub_diff(&waiter->to_event.expires,
     1217                                    &tv);
    12171218                                futex_up(&async_futex);
    12181219                        }
     
    15051506
    15061507        getuptime(&msg->wdata.to_event.expires);
    1507         tv_add(&msg->wdata.to_event.expires, timeout);
     1508        tv_add_diff(&msg->wdata.to_event.expires, timeout);
    15081509       
    15091510        /*
     
    15871588       
    15881589        getuptime(&msg->wdata.to_event.expires);
    1589         tv_add(&msg->wdata.to_event.expires, timeout);
     1590        tv_add_diff(&msg->wdata.to_event.expires, timeout);
    15901591       
    15911592        futex_down(&async_futex);
  • uspace/lib/c/generic/fibril.c

    r6069061 r58775d30  
    4949#include <assert.h>
    5050#include <async.h>
     51#include <futex.h>
     52
     53#ifdef FUTEX_UPGRADABLE
     54#include <rcu.h>
     55#endif
    5156
    5257/**
     
    5459 * serialized_list and manager_list.
    5560 */
    56 static atomic_t fibril_futex = FUTEX_INITIALIZER;
     61static futex_t fibril_futex = FUTEX_INITIALIZER;
    5762
    5863static LIST_INITIALIZE(ready_list);
     
    8388{
    8489        fibril_t *fibril = __tcb_get()->fibril_data;
     90
     91#ifdef FUTEX_UPGRADABLE
     92        rcu_register_fibril();
     93#endif
    8594       
    8695        /* Call the implementing function. */
     
    146155        int retval = 0;
    147156       
    148         futex_down(&fibril_futex);
     157        futex_lock(&fibril_futex);
    149158       
    150159        if (stype == FIBRIL_PREEMPT && list_empty(&ready_list))
     
    168177        if ((stype == FIBRIL_TO_MANAGER) || (stype == FIBRIL_FROM_DEAD)) {
    169178                while (list_empty(&manager_list)) {
    170                         futex_up(&fibril_futex);
     179                        futex_unlock(&fibril_futex);
    171180                        async_create_manager();
    172                         futex_down(&fibril_futex);
     181                        futex_lock(&fibril_futex);
    173182                }
    174183        }
     
    203212                        }
    204213                       
    205                         return 1;       /* futex_up already done here */
     214                        return 1;       /* futex_unlock already done here */
    206215                }
    207216               
     
    246255        list_remove(&dstf->link);
    247256       
    248         futex_up(&fibril_futex);
     257        futex_unlock(&fibril_futex);
     258       
     259#ifdef FUTEX_UPGRADABLE
     260        if (stype == FIBRIL_FROM_DEAD) {
     261                rcu_deregister_fibril();
     262        }
     263#endif
     264       
    249265        context_restore(&dstf->ctx);
    250266        /* not reached */
    251267       
    252268ret_0:
    253         futex_up(&fibril_futex);
     269        futex_unlock(&fibril_futex);
    254270        return retval;
    255271}
     
    318334        fibril_t *fibril = (fibril_t *) fid;
    319335       
    320         futex_down(&fibril_futex);
     336        futex_lock(&fibril_futex);
    321337       
    322338        if ((fibril->flags & FIBRIL_SERIALIZED))
     
    325341                list_append(&fibril->link, &ready_list);
    326342       
    327         futex_up(&fibril_futex);
     343        futex_unlock(&fibril_futex);
    328344}
    329345
     
    338354        fibril_t *fibril = (fibril_t *) fid;
    339355       
    340         futex_down(&fibril_futex);
     356        futex_lock(&fibril_futex);
    341357        list_append(&fibril->link, &manager_list);
    342         futex_up(&fibril_futex);
     358        futex_unlock(&fibril_futex);
    343359}
    344360
     
    346362void fibril_remove_manager(void)
    347363{
    348         futex_down(&fibril_futex);
     364        futex_lock(&fibril_futex);
    349365       
    350366        if (!list_empty(&manager_list))
    351367                list_remove(list_first(&manager_list));
    352368       
    353         futex_up(&fibril_futex);
     369        futex_unlock(&fibril_futex);
    354370}
    355371
  • uspace/lib/c/generic/fibril_synch.c

    r6069061 r58775d30  
    380380        if (timeout) {
    381381                getuptime(&wdata.to_event.expires);
    382                 tv_add(&wdata.to_event.expires, timeout);
     382                tv_add_diff(&wdata.to_event.expires, timeout);
    383383                async_insert_timeout(&wdata);
    384384        }
  • uspace/lib/c/generic/futex.c

    r6069061 r58775d30  
    3535#include <futex.h>
    3636#include <atomic.h>
    37 #include <libarch/barrier.h>
    38 #include <libc.h>
    39 #include <sys/types.h>
    4037
    4138/** Initialize futex counter.
     
    4744void futex_initialize(futex_t *futex, int val)
    4845{
    49         atomic_set(futex, val);
     46        atomic_set(&futex->val, val);
    5047}
    5148
    52 /** Try to down the futex.
    53  *
    54  * @param futex Futex.
    55  *
    56  * @return Non-zero if the futex was acquired.
    57  * @return Zero if the futex was not acquired.
    58  *
    59  */
    60 int futex_trydown(futex_t *futex)
     49
     50#ifdef FUTEX_UPGRADABLE
     51
     52int _upgrade_futexes = 0;
     53static futex_t upg_and_wait_futex = FUTEX_INITIALIZER;
     54
     55void futex_upgrade_all_and_wait(void)
    6156{
    62         int rc;
    63 
    64         rc = cas(futex, 1, 0);
    65         CS_ENTER_BARRIER();
    66 
    67         return rc;
     57        futex_down(&upg_and_wait_futex);
     58       
     59        if (!_upgrade_futexes) {
     60                rcu_assign(_upgrade_futexes, 1);
     61                _rcu_synchronize(BM_BLOCK_THREAD);
     62        }
     63       
     64        futex_up(&upg_and_wait_futex);
    6865}
    6966
    70 /** Down the futex.
    71  *
    72  * @param futex Futex.
    73  *
    74  * @return ENOENT if there is no such virtual address.
    75  * @return Zero in the uncontended case.
    76  * @return Otherwise one of ESYNCH_OK_ATOMIC or ESYNCH_OK_BLOCKED.
    77  *
    78  */
    79 int futex_down(futex_t *futex)
    80 {
    81         atomic_signed_t nv;
    82 
    83         nv = (atomic_signed_t) atomic_predec(futex);
    84         CS_ENTER_BARRIER();
    85         if (nv < 0)
    86                 return __SYSCALL1(SYS_FUTEX_SLEEP, (sysarg_t) &futex->count);
    87        
    88         return 0;
    89 }
    90 
    91 /** Up the futex.
    92  *
    93  * @param futex Futex.
    94  *
    95  * @return ENOENT if there is no such virtual address.
    96  * @return Zero in the uncontended case.
    97  *
    98  */
    99 int futex_up(futex_t *futex)
    100 {
    101         CS_LEAVE_BARRIER();
    102 
    103         if ((atomic_signed_t) atomic_postinc(futex) < 0)
    104                 return __SYSCALL1(SYS_FUTEX_WAKEUP, (sysarg_t) &futex->count);
    105        
    106         return 0;
    107 }
     67#endif
    10868
    10969/** @}
  • uspace/lib/c/generic/io/console.c

    r6069061 r58775d30  
    259259        struct timeval t1;
    260260        gettimeofday(&t1, NULL);
    261         *timeout -= tv_sub(&t1, &t0);
     261        *timeout -= tv_sub_diff(&t1, &t0);
    262262       
    263263        return true;
  • uspace/lib/c/generic/io/window.c

    r6069061 r58775d30  
    4040#include <stdio.h>
    4141
    42 int win_register(async_sess_t *sess, service_id_t *in, service_id_t *out)
     42int win_register(async_sess_t *sess, window_flags_t flags, service_id_t *in,
     43    service_id_t *out)
    4344{
    4445        async_exch_t *exch = async_exchange_begin(sess);
    45         int ret = async_req_0_2(exch, WINDOW_REGISTER, in, out);
     46        int ret = async_req_1_2(exch, WINDOW_REGISTER, flags, in, out);
    4647        async_exchange_end(exch);
    4748       
  • uspace/lib/c/generic/ipc.c

    r6069061 r58775d30  
    8181LIST_INITIALIZE(queued_calls);
    8282
    83 static atomic_t ipc_futex = FUTEX_INITIALIZER;
     83static futex_t ipc_futex = FUTEX_INITIALIZER;
    8484
    8585/** Send asynchronous message via syscall.
     
    136136        if (!call) {
    137137                /* Nothing to do regardless if failed or not */
    138                 futex_up(&ipc_futex);
     138                futex_unlock(&ipc_futex);
    139139                return;
    140140        }
    141141       
    142142        if (callid == (ipc_callid_t) IPC_CALLRET_FATAL) {
    143                 futex_up(&ipc_futex);
     143                futex_unlock(&ipc_futex);
    144144               
    145145                /* Call asynchronous handler with error code */
     
    152152       
    153153        if (callid == (ipc_callid_t) IPC_CALLRET_TEMPORARY) {
    154                 futex_up(&ipc_futex);
     154                futex_unlock(&ipc_futex);
    155155               
    156156                call->u.msg.phoneid = phoneid;
     
    175175        /* Add call to the list of dispatched calls */
    176176        list_append(&call->list, &dispatched_calls);
    177         futex_up(&ipc_futex);
     177        futex_unlock(&ipc_futex);
    178178}
    179179
     
    219219         */
    220220       
    221         futex_down(&ipc_futex);
     221        futex_lock(&ipc_futex);
    222222        ipc_callid_t callid = __SYSCALL6(SYS_IPC_CALL_ASYNC_FAST, phoneid,
    223223            imethod, arg1, arg2, arg3, arg4);
     
    226226                if (!call) {
    227227                        call = ipc_prepare_async(private, callback);
    228                         if (!call)
     228                        if (!call) {
     229                                futex_unlock(&ipc_futex);
    229230                                return;
     231                        }
    230232                }
    231233               
     
    289291         */
    290292       
    291         futex_down(&ipc_futex);
     293        futex_lock(&ipc_futex);
    292294        ipc_callid_t callid =
    293295            ipc_call_async_internal(phoneid, &call->u.msg.data);
     
    384386                        call->u.callid = callid;
    385387                       
    386                         futex_down(&ipc_futex);
     388                        futex_lock(&ipc_futex);
    387389                        list_append(&call->list, &dispatched_calls);
    388                         futex_up(&ipc_futex);
     390                        futex_unlock(&ipc_futex);
    389391                }
    390392               
     
    412414        callid &= ~IPC_CALLID_ANSWERED;
    413415       
    414         futex_down(&ipc_futex);
     416        futex_lock(&ipc_futex);
    415417       
    416418        link_t *item;
     
    423425                        list_remove(&call->list);
    424426                       
    425                         futex_up(&ipc_futex);
     427                        futex_unlock(&ipc_futex);
    426428                       
    427429                        if (call->callback)
     
    434436        }
    435437       
    436         futex_up(&ipc_futex);
     438        futex_unlock(&ipc_futex);
    437439}
    438440
  • uspace/lib/c/generic/libc.c

    r6069061 r58775d30  
    5252#include "private/io.h"
    5353
     54#ifdef FUTEX_UPGRADABLE
     55#include <rcu.h>
     56#endif
     57
    5458#ifdef CONFIG_RTLD
    5559#include <rtld/rtld.h>
    5660#endif
     61
    5762
    5863static bool env_setup = false;
     
    6267        /* Initialize user task run-time environment */
    6368        __malloc_init();
    64         __async_init();
    6569       
    6670        fibril_t *fibril = fibril_setup();
     
    7276        /* Save the PCB pointer */
    7377        __pcb = (pcb_t *) pcb_ptr;
     78       
     79#ifdef FUTEX_UPGRADABLE
     80        rcu_register_fibril();
     81#endif
     82       
     83        __async_init();
    7484       
    7585        /* The basic run-time environment is setup */
  • uspace/lib/c/generic/malloc.c

    r6069061 r58775d30  
    6767/** Heap shrink granularity
    6868 *
    69  * Try not to pump and stress the heap to much
     69 * Try not to pump and stress the heap too much
    7070 * by shrinking and enlarging it too often.
    71  * A heap area won't shrunk if it the released
     71 * A heap area won't shrink if the released
    7272 * free block is smaller than this constant.
    7373 *
     
    200200        do { \
    201201                if (!(expr)) {\
    202                         futex_up(&malloc_futex); \
     202                        heap_unlock(); \
    203203                        assert_abort(#expr, __FILE__, __LINE__); \
    204204                } \
     
    210210
    211211#endif /* NDEBUG */
     212
     213
     214#ifdef FUTEX_UPGRADABLE
     215/** True if the heap may be accessed from multiple threads. */
     216static bool multithreaded = false;
     217
     218/** Makes accesses to the heap thread safe. */
     219void malloc_enable_multithreaded(void)
     220{
     221        multithreaded = true;
     222}
     223
     224/** Serializes access to the heap from multiple threads. */
     225static inline void heap_lock(void)
     226{
     227        if (multithreaded) {
     228                futex_down(&malloc_futex);
     229        } else {
     230                /*
     231                 * Malloc never switches fibrils while the heap is locked.
     232                 * Similarly, it never creates new threads from within the
     233                 * locked region. Therefore, if there are no other threads
     234                 * except this one, the whole operation will complete without
     235                 * any interruptions.
     236                 */
     237        }
     238}
     239
     240/** Serializes access to the heap from multiple threads. */
     241static inline void heap_unlock(void)
     242{
     243        if (multithreaded) {
     244                futex_up(&malloc_futex);
     245        } else {
     246                /*
     247                 * Malloc never switches fibrils while the heap is locked.
     248                 * Similarly, it never creates new threads from within the
     249                 * locked region. Therefore, if there are no other threads
     250                 * except this one, the whole operation will complete without
     251                 * any interruptions.
     252                 */
     253        }
     254}
     255
     256#else
     257
     258/** Makes accesses to the heap thread safe. */
     259void malloc_enable_multithreaded(void)
     260{
     261        /* No-op. Already using thread-safe heap locking operations. */
     262}
     263
     264/** Serializes access to the heap from multiple threads. */
     265static inline void heap_lock(void)
     266{
     267        futex_down(&malloc_futex);
     268}
     269
     270/** Serializes access to the heap from multiple threads. */
     271static inline void heap_unlock(void)
     272{
     273        futex_up(&malloc_futex);
     274}
     275#endif
     276
    212277
    213278/** Initialize a heap block
     
    785850void *malloc(const size_t size)
    786851{
    787         futex_down(&malloc_futex);
     852        heap_lock();
    788853        void *block = malloc_internal(size, BASE_ALIGN);
    789         futex_up(&malloc_futex);
    790        
     854        heap_unlock();
     855
    791856        return block;
    792857}
     
    807872        size_t palign =
    808873            1 << (fnzb(max(sizeof(void *), align) - 1) + 1);
    809        
    810         futex_down(&malloc_futex);
     874
     875        heap_lock();
    811876        void *block = malloc_internal(size, palign);
    812         futex_up(&malloc_futex);
    813        
     877        heap_unlock();
     878
    814879        return block;
    815880}
     
    828893                return malloc(size);
    829894       
    830         futex_down(&malloc_futex);
     895        heap_lock();
    831896       
    832897        /* Calculate the position of the header. */
     
    885950        }
    886951       
    887         futex_up(&malloc_futex);
     952        heap_unlock();
    888953       
    889954        if (reloc) {
     
    908973                return;
    909974       
    910         futex_down(&malloc_futex);
     975        heap_lock();
    911976       
    912977        /* Calculate the position of the header. */
     
    9531018        heap_shrink(area);
    9541019       
    955         futex_up(&malloc_futex);
     1020        heap_unlock();
    9561021}
    9571022
    9581023void *heap_check(void)
    9591024{
    960         futex_down(&malloc_futex);
     1025        heap_lock();
    9611026       
    9621027        if (first_heap_area == NULL) {
    963                 futex_up(&malloc_futex);
     1028                heap_unlock();
    9641029                return (void *) -1;
    9651030        }
     
    9751040                    (((uintptr_t) area->start % PAGE_SIZE) != 0) ||
    9761041                    (((uintptr_t) area->end % PAGE_SIZE) != 0)) {
    977                         futex_up(&malloc_futex);
     1042                        heap_unlock();
    9781043                        return (void *) area;
    9791044                }
     
    9861051                        /* Check heap block consistency */
    9871052                        if (head->magic != HEAP_BLOCK_HEAD_MAGIC) {
    988                                 futex_up(&malloc_futex);
     1053                                heap_unlock();
    9891054                                return (void *) head;
    9901055                        }
     
    9941059                        if ((foot->magic != HEAP_BLOCK_FOOT_MAGIC) ||
    9951060                            (head->size != foot->size)) {
    996                                 futex_up(&malloc_futex);
     1061                                heap_unlock();
    9971062                                return (void *) foot;
    9981063                        }
     
    10001065        }
    10011066       
    1002         futex_up(&malloc_futex);
     1067        heap_unlock();
    10031068       
    10041069        return NULL;
  • uspace/lib/c/generic/thread.c

    r6069061 r58775d30  
    4646#include "private/thread.h"
    4747
     48#ifdef FUTEX_UPGRADABLE
     49#include <rcu.h>
     50#endif
     51
     52
    4853/** Main thread function.
    4954 *
     
    6368        __tcb_set(fibril->tcb);
    6469       
     70#ifdef FUTEX_UPGRADABLE
     71        rcu_register_fibril();
     72        futex_upgrade_all_and_wait();
     73#endif
     74       
    6575        uarg->uspace_thread_function(uarg->uspace_thread_arg);
    6676        /*
     
    7383        /* If there is a manager, destroy it */
    7484        async_destroy_manager();
     85
     86#ifdef FUTEX_UPGRADABLE
     87        rcu_deregister_fibril();
     88#endif
     89       
    7590        fibril_teardown(fibril);
    7691       
     
    106121                return ENOMEM;
    107122        }
     123       
     124        /* Make heap thread safe. */
     125        malloc_enable_multithreaded();
    108126       
    109127        uarg->uspace_entry = (void *) FADDR(__thread_entry);
  • uspace/lib/c/generic/time.c

    r6069061 r58775d30  
    5959#define MINS_PER_HOUR  60
    6060#define SECS_PER_MIN   60
     61#define USECS_PER_SEC  1000000
    6162#define MINS_PER_DAY   (MINS_PER_HOUR * HOURS_PER_DAY)
    6263#define SECS_PER_HOUR  (SECS_PER_MIN * MINS_PER_HOUR)
     
    252253 * Optionally add specified amount of seconds.
    253254 *
    254  * @param tm      Broken-down time to normalize.
    255  * @param sec_add Seconds to add.
     255 * @param tm Broken-down time to normalize.
     256 * @param tv Timeval to add.
    256257 *
    257258 * @return 0 on success, -1 on overflow
    258259 *
    259260 */
    260 static int normalize_time(struct tm *tm, time_t sec_add)
     261static int normalize_tm_tv(struct tm *tm, const struct timeval *tv)
    261262{
    262263        // TODO: DST correction
    263264       
    264265        /* Set initial values. */
    265         time_t sec = tm->tm_sec + sec_add;
     266        time_t usec = tm->tm_usec + tv->tv_usec;
     267        time_t sec = tm->tm_sec + tv->tv_sec;
    266268        time_t min = tm->tm_min;
    267269        time_t hour = tm->tm_hour;
     
    271273       
    272274        /* Adjust time. */
     275        sec += floor_div(usec, USECS_PER_SEC);
     276        usec = floor_mod(usec, USECS_PER_SEC);
    273277        min += floor_div(sec, SECS_PER_MIN);
    274278        sec = floor_mod(sec, SECS_PER_MIN);
     
    319323       
    320324        /* And put the values back to the struct. */
     325        tm->tm_usec = (int) usec;
    321326        tm->tm_sec = (int) sec;
    322327        tm->tm_min = (int) min;
     
    335340}
    336341
     342static int normalize_tm_time(struct tm *tm, time_t time)
     343{
     344        struct timeval tv = {
     345                .tv_sec = time,
     346                .tv_usec = 0
     347        };
     348
     349        return normalize_tm_tv(tm, &tv);
     350}
     351
     352
    337353/** Which day the week-based year starts on.
    338354 *
     
    442458}
    443459
     460static void tv_normalize(struct timeval *tv)
     461{
     462        while (tv->tv_usec > USECS_PER_SEC) {
     463                tv->tv_sec++;
     464                tv->tv_usec -= USECS_PER_SEC;
     465        }
     466        while (tv->tv_usec < 0) {
     467                tv->tv_sec--;
     468                tv->tv_usec += USECS_PER_SEC;
     469        }
     470}
     471
    444472/** Add microseconds to given timeval.
    445473 *
     
    448476 *
    449477 */
    450 void tv_add(struct timeval *tv, suseconds_t usecs)
    451 {
    452         tv->tv_sec += usecs / 1000000;
    453         tv->tv_usec += usecs % 1000000;
    454        
    455         if (tv->tv_usec > 1000000) {
    456                 tv->tv_sec++;
    457                 tv->tv_usec -= 1000000;
    458         }
    459 }
    460 
    461 /** Subtract two timevals.
     478void tv_add_diff(struct timeval *tv, suseconds_t usecs)
     479{
     480        tv->tv_sec += usecs / USECS_PER_SEC;
     481        tv->tv_usec += usecs % USECS_PER_SEC;
     482        tv_normalize(tv);
     483}
     484
     485/** Add two timevals.
    462486 *
    463487 * @param tv1 First timeval.
    464488 * @param tv2 Second timeval.
     489 */
     490void tv_add(struct timeval *tv1, struct timeval *tv2)
     491{
     492        tv1->tv_sec += tv2->tv_sec;
     493        tv1->tv_usec += tv2->tv_usec;
     494        tv_normalize(tv1);
     495}
     496
     497/** Subtract two timevals.
     498 *
     499 * @param tv1 First timeval.
     500 * @param tv2 Second timeval.
    465501 *
    466502 * @return Difference between tv1 and tv2 (tv1 - tv2) in
     
    468504 *
    469505 */
    470 suseconds_t tv_sub(struct timeval *tv1, struct timeval *tv2)
     506suseconds_t tv_sub_diff(struct timeval *tv1, struct timeval *tv2)
    471507{
    472508        return (tv1->tv_usec - tv2->tv_usec) +
    473             ((tv1->tv_sec - tv2->tv_sec) * 1000000);
     509            ((tv1->tv_sec - tv2->tv_sec) * USECS_PER_SEC);
     510}
     511
     512/** Subtract two timevals.
     513 *
     514 * @param tv1 First timeval.
     515 * @param tv2 Second timeval.
     516 *
     517 */
     518void tv_sub(struct timeval *tv1, struct timeval *tv2)
     519{
     520        tv1->tv_sec -= tv2->tv_sec;
     521        tv1->tv_usec -= tv2->tv_usec;
     522        tv_normalize(tv1);
    474523}
    475524
     
    573622                goto fallback;
    574623       
    575         tv->tv_usec = 0;
     624        tv->tv_usec = time.tm_usec;
    576625        tv->tv_sec = mktime(&time);
    577626       
     
    689738        // TODO: detect overflow
    690739       
    691         normalize_time(tm, 0);
     740        normalize_tm_time(tm, 0);
    692741        return secs_since_epoch(tm);
    693742}
     
    944993       
    945994        /* Set result to epoch. */
     995        result->tm_usec = 0;
    946996        result->tm_sec = 0;
    947997        result->tm_min = 0;
     
    9511001        result->tm_year = 70; /* 1970 */
    9521002       
    953         if (normalize_time(result, time) == -1)
     1003        if (normalize_tm_time(result, time) == -1)
    9541004                return EOVERFLOW;
    9551005       
     
    10141064 * Time is expressed relative to the user's specified timezone.
    10151065 *
    1016  * @param timer  Time to convert.
     1066 * @param tv     Timeval to convert.
    10171067 * @param result Structure to store the result to.
    10181068 *
     
    10201070 *
    10211071 */
    1022 int time_local2tm(const time_t time, struct tm *restrict result)
     1072int time_tv2tm(const struct timeval *tv, struct tm *restrict result)
    10231073{
    10241074        // TODO: Deal with timezones.
     
    10261076       
    10271077        /* Set result to epoch. */
     1078        result->tm_usec = 0;
    10281079        result->tm_sec = 0;
    10291080        result->tm_min = 0;
     
    10331084        result->tm_year = 70; /* 1970 */
    10341085       
    1035         if (normalize_time(result, time) == -1)
     1086        if (normalize_tm_tv(result, tv) == -1)
    10361087                return EOVERFLOW;
    10371088       
    10381089        return EOK;
     1090}
     1091
     1092/** Converts a time value to a broken-down local time.
     1093 *
     1094 * Time is expressed relative to the user's specified timezone.
     1095 *
     1096 * @param timer  Time to convert.
     1097 * @param result Structure to store the result to.
     1098 *
     1099 * @return EOK on success or a negative error code.
     1100 *
     1101 */
     1102int time_local2tm(const time_t time, struct tm *restrict result)
     1103{
     1104        struct timeval tv = {
     1105                .tv_sec = time,
     1106                .tv_usec = 0
     1107        };
     1108
     1109        return time_tv2tm(&tv, result);
    10391110}
    10401111
  • uspace/lib/c/include/adt/list.h

    r6069061 r58775d30  
    5858 */
    5959#define LIST_INITIALIZE(name) \
    60         list_t name = { \
     60        list_t name = LIST_INITIALIZER(name)
     61
     62/** Initializer for statically allocated list.
     63 *
     64 * @code
     65 * struct named_list {
     66 *     const char *name;
     67 *     list_t list;
     68 * } var = {
     69 *     .name = "default name",
     70 *     .list = LIST_INITIALIZER(name_list.list)
     71 * };
     72 * @endcode
     73 *
     74 * @param name Name of the new statically allocated list.
     75 *
     76 */
     77#define LIST_INITIALIZER(name) \
     78        { \
    6179                .head = { \
    6280                        .prev = &(name).head, \
  • uspace/lib/c/include/futex.h

    r6069061 r58775d30  
    3838#include <atomic.h>
    3939#include <sys/types.h>
     40#include <libc.h>
    4041
    41 #define FUTEX_INITIALIZER  {1}
     42typedef struct futex {
     43        atomic_t val;
     44#ifdef FUTEX_UPGRADABLE
     45        int upgraded;
     46#endif
     47} futex_t;
    4248
    43 typedef atomic_t futex_t;
    4449
    4550extern void futex_initialize(futex_t *futex, int value);
    46 extern int futex_down(futex_t *futex);
    47 extern int futex_trydown(futex_t *futex);
    48 extern int futex_up(futex_t *futex);
     51
     52#ifdef FUTEX_UPGRADABLE
     53#include <rcu.h>
     54
     55#define FUTEX_INITIALIZE(val) {{ (val) }, 0}
     56
     57#define futex_lock(fut) \
     58({ \
     59        rcu_read_lock(); \
     60        (fut)->upgraded = rcu_access(_upgrade_futexes); \
     61        if ((fut)->upgraded) \
     62                (void) futex_down((fut)); \
     63})
     64
     65#define futex_trylock(fut) \
     66({ \
     67        rcu_read_lock(); \
     68        int _upgraded = rcu_access(_upgrade_futexes); \
     69        if (_upgraded) { \
     70                int _acquired = futex_trydown((fut)); \
     71                if (!_acquired) { \
     72                        rcu_read_unlock(); \
     73                } else { \
     74                        (fut)->upgraded = true; \
     75                } \
     76                _acquired; \
     77        } else { \
     78                (fut)->upgraded = false; \
     79                1; \
     80        } \
     81})
     82               
     83#define futex_unlock(fut) \
     84({ \
     85        if ((fut)->upgraded) \
     86                (void) futex_up((fut)); \
     87        rcu_read_unlock(); \
     88})
     89
     90extern int _upgrade_futexes;
     91
     92extern void futex_upgrade_all_and_wait(void);
     93               
     94#else
     95
     96#define FUTEX_INITIALIZE(val) {{ (val) }}
     97
     98#define futex_lock(fut)     (void) futex_down((fut))
     99#define futex_trylock(fut)  futex_trydown((fut))
     100#define futex_unlock(fut)   (void) futex_up((fut))
     101               
     102#endif
     103
     104#define FUTEX_INITIALIZER     FUTEX_INITIALIZE(1)
     105
     106/** Try to down the futex.
     107 *
     108 * @param futex Futex.
     109 *
     110 * @return Non-zero if the futex was acquired.
     111 * @return Zero if the futex was not acquired.
     112 *
     113 */
     114static inline int futex_trydown(futex_t *futex)
     115{
     116        return cas(&futex->val, 1, 0);
     117}
     118
     119/** Down the futex.
     120 *
     121 * @param futex Futex.
     122 *
     123 * @return ENOENT if there is no such virtual address.
     124 * @return Zero in the uncontended case.
     125 * @return Otherwise one of ESYNCH_OK_ATOMIC or ESYNCH_OK_BLOCKED.
     126 *
     127 */
     128static inline int futex_down(futex_t *futex)
     129{
     130        if ((atomic_signed_t) atomic_predec(&futex->val) < 0)
     131                return __SYSCALL1(SYS_FUTEX_SLEEP, (sysarg_t) &futex->val.count);
     132       
     133        return 0;
     134}
     135
     136/** Up the futex.
     137 *
     138 * @param futex Futex.
     139 *
     140 * @return ENOENT if there is no such virtual address.
     141 * @return Zero in the uncontended case.
     142 *
     143 */
     144static inline int futex_up(futex_t *futex)
     145{
     146        if ((atomic_signed_t) atomic_postinc(&futex->val) < 0)
     147                return __SYSCALL1(SYS_FUTEX_WAKEUP, (sysarg_t) &futex->val.count);
     148       
     149        return 0;
     150}
    49151
    50152#endif
  • uspace/lib/c/include/io/window.h

    r6069061 r58775d30  
    4242#include <io/kbd_event.h>
    4343#include <io/pos_event.h>
     44
     45typedef enum {
     46        WINDOW_MAIN = 1,
     47        WINDOW_DECORATED = 2,
     48        WINDOW_RESIZEABLE = 4
     49} window_flags_t;
    4450
    4551typedef enum {
     
    108114} window_event_t;
    109115
    110 extern int win_register(async_sess_t *, service_id_t *, service_id_t *);
     116extern int win_register(async_sess_t *, window_flags_t, service_id_t *,
     117    service_id_t *);
    111118
    112119extern int win_get_event(async_sess_t *, window_event_t *);
  • uspace/lib/c/include/ipc/common.h

    r6069061 r58775d30  
    4040#include <atomic.h>
    4141#include <abi/proc/task.h>
     42#include <futex.h>
    4243
    4344#define IPC_FLAG_BLOCKING  0x01
     
    5152typedef sysarg_t ipc_callid_t;
    5253
    53 extern atomic_t async_futex;
     54extern futex_t async_futex;
    5455
    5556#endif
  • uspace/lib/c/include/malloc.h

    r6069061 r58775d30  
    4848extern void *heap_check(void);
    4949
     50extern void malloc_enable_multithreaded(void);
    5051#endif
    5152
  • uspace/lib/c/include/rwlock.h

    r6069061 r58775d30  
    4949
    5050#define rwlock_initialize(rwlock)       futex_initialize((rwlock), 1)
    51 #define rwlock_read_lock(rwlock)        futex_down((rwlock))
    52 #define rwlock_write_lock(rwlock)       futex_down((rwlock))
    53 #define rwlock_read_unlock(rwlock)      futex_up((rwlock))
    54 #define rwlock_write_unlock(rwlock)     futex_up((rwlock))
     51#define rwlock_read_lock(rwlock)        futex_lock((rwlock))
     52#define rwlock_write_lock(rwlock)       futex_lock((rwlock))
     53#define rwlock_read_unlock(rwlock)      futex_unlock((rwlock))
     54#define rwlock_write_unlock(rwlock)     futex_unlock((rwlock))
    5555
    5656#endif
  • uspace/lib/c/include/sys/time.h

    r6069061 r58775d30  
    5050
    5151struct tm {
     52        int tm_usec;   /* Microseconds [0,999999]. */
    5253        int tm_sec;    /* Seconds [0,60]. */
    5354        int tm_min;    /* Minutes [0,59]. */
     
    7172};
    7273
    73 extern void tv_add(struct timeval *, suseconds_t);
    74 extern suseconds_t tv_sub(struct timeval *, struct timeval *);
     74extern void tv_add_diff(struct timeval *, suseconds_t);
     75extern void tv_add(struct timeval *, struct timeval *);
     76extern suseconds_t tv_sub_diff(struct timeval *, struct timeval *);
     77extern void tv_sub(struct timeval *, struct timeval *);
    7578extern int tv_gt(struct timeval *, struct timeval *);
    7679extern int tv_gteq(struct timeval *, struct timeval *);
     
    7982
    8083extern void udelay(useconds_t);
     84extern int usleep(useconds_t);
    8185
    8286extern time_t mktime(struct tm *);
     
    8488extern int time_utc2str(const time_t, char *);
    8589extern void time_tm2str(const struct tm *, char *);
     90extern int time_tv2tm(const struct timeval *, struct tm *);
    8691extern int time_local2tm(const time_t, struct tm *);
    8792extern int time_local2str(const time_t, char *);
  • uspace/lib/compress/gzip.c

    r6069061 r58775d30  
    3232#include <malloc.h>
    3333#include <unistd.h>
     34#include <byteorder.h>
    3435#include "gzip.h"
    3536#include "inflate.h"
     
    103104                return EINVAL;
    104105       
    105         *destlen = footer.size;
     106        *destlen = uint32_t_le2host(footer.size);
    106107       
    107108        /* Ignore extra metadata */
  • uspace/lib/gui/window.c

    r6069061 r58775d30  
    591591}
    592592
    593 window_t *window_open(const char *winreg, bool is_main, bool is_decorated,
     593window_t *window_open(const char *winreg, window_flags_t flags,
    594594    const char *caption)
    595595{
     
    598598                return NULL;
    599599       
    600         win->is_main = is_main;
    601         win->is_decorated = is_decorated;
     600        win->is_main = flags & WINDOW_MAIN;
     601        win->is_decorated = flags & WINDOW_DECORATED;
    602602        win->is_focused = true;
    603603        prodcons_initialize(&win->events);
     
    632632        service_id_t in_dsid;
    633633        service_id_t out_dsid;
    634         rc = win_register(reg_sess, &in_dsid, &out_dsid);
     634        rc = win_register(reg_sess, flags, &in_dsid, &out_dsid);
    635635        async_hangup(reg_sess);
    636636        if (rc != EOK) {
  • uspace/lib/gui/window.h

    r6069061 r58775d30  
    6565 * Allocate all resources for new window and register it in the compositor.
    6666 * If the window is declared as main, its closure causes termination of the
    67  * whole application. Note that opened window does not have any surface yet. */
    68 extern window_t *window_open(const char *, bool, bool, const char *);
     67 * whole application. Note that opened window does not have any surface yet.
     68 */
     69extern window_t *window_open(const char *, window_flags_t, const char *);
    6970
    7071/**
  • uspace/lib/math/arch/abs32le/include/libarch/math.h

    r6069061 r58775d30  
    4141#include <trig.h>
    4242
    43 static inline double fmod(double dividend, double divisor)
     43static inline float64_t fmod(float64_t dividend, float64_t divisor)
    4444{
    45         return double_mod(dividend, divisor);
     45        return float64_mod(dividend, divisor);
    4646}
    4747
    48 static inline double trunc(double val)
     48static inline float64_t trunc(float64_t val)
    4949{
    50         double_t arg;
     50        float64_u arg;
    5151        arg.val = val;
    5252       
    53         double_t ret;
     53        float64_u ret;
    5454        ret.data = trunc_float64(arg.data);
    5555       
     
    5757}
    5858
    59 static inline double sin(double val)
     59static inline float64_t sin(float64_t val)
    6060{
    61         return double_sin(val);
     61        return float64_sin(val);
    6262}
    6363
    64 static inline double cos(double val)
     64static inline float64_t cos(float64_t val)
    6565{
    66         return double_cos(val);
     66        return float64_cos(val);
    6767}
    6868
  • uspace/lib/math/arch/amd64/include/libarch/math.h

    r6069061 r58775d30  
    3636#define LIBMATH_amd64_MATH_H_
    3737
     38#include <mathtypes.h>
    3839#include <mod.h>
    3940
    40 static inline double fmod(double dividend, double divisor)
     41static inline float64_t fmod(float64_t dividend, float64_t divisor)
    4142{
    42         return double_mod(dividend, divisor);
     43        return float64_mod(dividend, divisor);
    4344}
    4445
    45 extern double sin(double);
    46 extern double cos(double);
    47 extern double trunc(double);
     46extern float64_t sin(float64_t);
     47extern float64_t cos(float64_t);
     48extern float64_t trunc(float64_t);
    4849
    4950#endif
  • uspace/lib/math/arch/arm32/include/libarch/math.h

    r6069061 r58775d30  
    4141#include <trig.h>
    4242
    43 static inline double fmod(double dividend, double divisor)
     43static inline float64_t fmod(float64_t dividend, float64_t divisor)
    4444{
    45         return double_mod(dividend, divisor);
     45        return float64_mod(dividend, divisor);
    4646}
    4747
    48 static inline double trunc(double val)
     48static inline float64_t trunc(float64_t val)
    4949{
    50         double_t arg;
     50        float64_u arg;
    5151        arg.val = val;
    5252       
    53         double_t ret;
     53        float64_u ret;
    5454        ret.data = trunc_float64(arg.data);
    5555       
     
    5757}
    5858
    59 static inline double sin(double val)
     59static inline float64_t sin(float64_t val)
    6060{
    61         return double_sin(val);
     61        return float64_sin(val);
    6262}
    6363
    64 static inline double cos(double val)
     64static inline float64_t cos(float64_t val)
    6565{
    66         return double_cos(val);
     66        return float64_cos(val);
    6767}
    6868
  • uspace/lib/math/arch/ia32/include/libarch/math.h

    r6069061 r58775d30  
    3636#define LIBMATH_ia32_MATH_H_
    3737
     38#include <mathtypes.h>
    3839#include <mod.h>
    3940
    40 static inline double fmod(double dividend, double divisor)
     41static inline float64_t fmod(float64_t dividend, float64_t divisor)
    4142{
    42         return double_mod(dividend, divisor);
     43        return float64_mod(dividend, divisor);
    4344}
    4445
    45 extern double sin(double);
    46 extern double cos(double);
    47 extern double trunc(double);
     46extern float64_t sin(float64_t);
     47extern float64_t cos(float64_t);
     48extern float64_t trunc(float64_t);
    4849
    4950#endif
  • uspace/lib/math/arch/ia64/include/libarch/math.h

    r6069061 r58775d30  
    4141#include <trig.h>
    4242
    43 static inline double fmod(double dividend, double divisor)
     43static inline float64_t fmod(float64_t dividend, float64_t divisor)
    4444{
    45         return double_mod(dividend, divisor);
     45        return float64_mod(dividend, divisor);
    4646}
    4747
    48 static inline double trunc(double val)
     48static inline float64_t trunc(float64_t val)
    4949{
    50         double_t arg;
     50        float64_u arg;
    5151        arg.val = val;
    5252       
    53         double_t ret;
     53        float64_u ret;
    5454        ret.data = trunc_float64(arg.data);
    5555       
     
    5757}
    5858
    59 static inline double sin(double val)
     59static inline float64_t sin(float64_t val)
    6060{
    61         return double_sin(val);
     61        return float64_sin(val);
    6262}
    6363
    64 static inline double cos(double val)
     64static inline float64_t cos(float64_t val)
    6565{
    66         return double_cos(val);
     66        return float64_cos(val);
    6767}
    6868
  • uspace/lib/math/arch/mips32/include/libarch/math.h

    r6069061 r58775d30  
    4141#include <trig.h>
    4242
    43 static inline double fmod(double dividend, double divisor)
     43static inline float64_t fmod(float64_t dividend, float64_t divisor)
    4444{
    45         return double_mod(dividend, divisor);
     45        return float64_mod(dividend, divisor);
    4646}
    4747
    48 static inline double trunc(double val)
     48static inline float64_t trunc(float64_t val)
    4949{
    50         double_t arg;
     50        float64_u arg;
    5151        arg.val = val;
    5252       
    53         double_t ret;
     53        float64_u ret;
    5454        ret.data = trunc_float64(arg.data);
    5555       
     
    5757}
    5858
    59 static inline double sin(double val)
     59static inline float64_t sin(float64_t val)
    6060{
    61         return double_sin(val);
     61        return float64_sin(val);
    6262}
    6363
    64 static inline double cos(double val)
     64static inline float64_t cos(float64_t val)
    6565{
    66         return double_cos(val);
     66        return float64_cos(val);
    6767}
    6868
  • uspace/lib/math/arch/mips32eb/include/libarch/math.h

    r6069061 r58775d30  
    4141#include <trig.h>
    4242
    43 static inline double fmod(double dividend, double divisor)
     43static inline float64_t fmod(float64_t dividend, float64_t divisor)
    4444{
    45         return double_mod(dividend, divisor);
     45        return float64_mod(dividend, divisor);
    4646}
    4747
    48 static inline double trunc(double val)
     48static inline float64_t trunc(float64_t val)
    4949{
    50         double_t arg;
     50        float64_u arg;
    5151        arg.val = val;
    5252       
    53         double_t ret;
     53        float64_u ret;
    5454        ret.data = trunc_float64(arg.data);
    5555       
     
    5757}
    5858
    59 static inline double sin(double val)
     59static inline float64_t sin(float64_t val)
    6060{
    61         return double_sin(val);
     61        return float64_sin(val);
    6262}
    6363
    64 static inline double cos(double val)
     64static inline float64_t cos(float64_t val)
    6565{
    66         return double_cos(val);
     66        return float64_cos(val);
    6767}
    6868
  • uspace/lib/math/arch/ppc32/include/libarch/math.h

    r6069061 r58775d30  
    4141#include <trig.h>
    4242
    43 static inline double fmod(double dividend, double divisor)
     43static inline float64_t fmod(float64_t dividend, float64_t divisor)
    4444{
    45         return double_mod(dividend, divisor);
     45        return float64_mod(dividend, divisor);
    4646}
    4747
    4848static inline double trunc(double val)
    4949{
    50         double_t arg;
     50        float64_u arg;
    5151        arg.val = val;
    5252       
    53         double_t ret;
     53        float64_u ret;
    5454        ret.data = trunc_float64(arg.data);
    5555       
     
    5757}
    5858
    59 static inline double sin(double val)
     59static inline float64_t sin(float64_t val)
    6060{
    61         return double_sin(val);
     61        return float64_sin(val);
    6262}
    6363
    64 static inline double cos(double val)
     64static inline float64_t cos(float64_t val)
    6565{
    66         return double_cos(val);
     66        return float64_cos(val);
    6767}
    6868
  • uspace/lib/math/arch/sparc32/include/libarch/math.h

    r6069061 r58775d30  
    4141#include <trig.h>
    4242
    43 static inline double fmod(double dividend, double divisor)
     43static inline float64_t fmod(float64_t dividend, float64_t divisor)
    4444{
    45         return double_mod(dividend, divisor);
     45        return float64_mod(dividend, divisor);
    4646}
    4747
    48 static inline double trunc(double val)
     48static inline float64_t trunc(float64_t val)
    4949{
    50         double_t arg;
     50        float64_u arg;
    5151        arg.val = val;
    5252       
    53         double_t ret;
     53        float64_u ret;
    5454        ret.data = trunc_float64(arg.data);
    5555       
     
    5757}
    5858
    59 static inline double sin(double val)
     59static inline float64_t sin(float64_t val)
    6060{
    61         return double_sin(val);
     61        return float64_sin(val);
    6262}
    6363
    64 static inline double cos(double val)
     64static inline float64_t cos(float64_t val)
    6565{
    66         return double_cos(val);
     66        return float64_cos(val);
    6767}
    6868
  • uspace/lib/math/arch/sparc64/include/libarch/math.h

    r6069061 r58775d30  
    4141#include <trig.h>
    4242
    43 static inline double fmod(double dividend, double divisor)
     43static inline float64_t fmod(float64_t dividend, float64_t divisor)
    4444{
    45         return double_mod(dividend, divisor);
     45        return float64_mod(dividend, divisor);
    4646}
    4747
    48 static inline double trunc(double val)
     48static inline float64_t trunc(float64_t val)
    4949{
    50         double_t arg;
     50        float64_u arg;
    5151        arg.val = val;
    5252       
    53         double_t ret;
     53        float64_u ret;
    5454        ret.data = trunc_float64(arg.data);
    5555       
     
    5757}
    5858
    59 static inline double sin(double val)
     59static inline float64_t sin(float64_t val)
    6060{
    61         return double_sin(val);
     61        return float64_sin(val);
    6262}
    6363
    64 static inline double cos(double val)
     64static inline float64_t cos(float64_t val)
    6565{
    66         return double_cos(val);
     66        return float64_cos(val);
    6767}
    6868
  • uspace/lib/math/generic/mod.c

    r6069061 r58775d30  
    5252 *
    5353 */
    54 double double_mod(double dividend, double divisor)
     54float64_t float64_mod(float64_t dividend, float64_t divisor)
    5555{
    5656        // FIXME: replace with exact arithmetics
    5757       
    58         double quotient = trunc(dividend / divisor);
     58        float64_t quotient = trunc(dividend / divisor);
    5959       
    6060        return (dividend - quotient * divisor);
  • uspace/lib/math/generic/trig.c

    r6069061 r58775d30  
    3939
    4040/** Precomputed values for factorial (starting from 1!) */
    41 static double factorials[TAYLOR_DEGREE] = {
     41static float64_t factorials[TAYLOR_DEGREE] = {
    4242        1, 2, 6, 24, 120, 720, 5040, 40320, 362880, 3628800, 39916800,
    4343        479001600, 6227020800
     
    5656 *
    5757 */
    58 static double taylor_sin(double arg)
    59 {
    60         double ret = 0;
    61         double nom = 1;
     58static float64_t taylor_sin(float64_t arg)
     59{
     60        float64_t ret = 0;
     61        float64_t nom = 1;
    6262       
    6363        for (unsigned int i = 0; i < TAYLOR_DEGREE; i++) {
     
    8585 *
    8686 */
    87 static double taylor_cos(double arg)
    88 {
    89         double ret = 1;
    90         double nom = 1;
     87static float64_t taylor_cos(float64_t arg)
     88{
     89        float64_t ret = 1;
     90        float64_t nom = 1;
    9191       
    9292        for (unsigned int i = 0; i < TAYLOR_DEGREE; i++) {
     
    114114 *
    115115 */
    116 static double base_sin(double arg)
     116static float64_t base_sin(float64_t arg)
    117117{
    118118        unsigned int period = arg / (M_PI / 4);
     
    147147 *
    148148 */
    149 static double base_cos(double arg)
     149static float64_t base_cos(float64_t arg)
    150150{
    151151        unsigned int period = arg / (M_PI / 4);
     
    156156        case 1:
    157157        case 2:
    158                 return taylor_sin(arg - M_PI / 2);
     158                return -taylor_sin(arg - M_PI / 2);
    159159        case 3:
    160160        case 4:
     
    162162        case 5:
    163163        case 6:
    164                 return -taylor_sin(arg - 3 * M_PI / 2);
     164                return taylor_sin(arg - 3 * M_PI / 2);
    165165        default:
    166166                return taylor_cos(arg - 2 * M_PI);
     
    177177 *
    178178 */
    179 double double_sin(double arg)
    180 {
    181         double base_arg = fmod(arg, 2 * M_PI);
     179float64_t float64_sin(float64_t arg)
     180{
     181        float64_t base_arg = fmod(arg, 2 * M_PI);
    182182       
    183183        if (base_arg < 0)
     
    196196 *
    197197 */
    198 double double_cos(double arg)
    199 {
    200         double base_arg = fmod(arg, 2 * M_PI);
     198float64_t float64_cos(float64_t arg)
     199{
     200        float64_t base_arg = fmod(arg, 2 * M_PI);
    201201       
    202202        if (base_arg < 0)
  • uspace/lib/math/generic/trunc.c

    r6069061 r58775d30  
    6868        } else {
    6969                /* Truncate irrelevant fraction bits */
    70                 val.parts.fraction &= UINT64_C(0x000fffffffffffff) >> exp;
     70                val.parts.fraction &= ~(UINT64_C(0x000fffffffffffff) >> exp);
    7171        }
    7272       
  • uspace/lib/math/include/mathtypes.h

    r6069061 r58775d30  
    191191#endif
    192192
    193 typedef union {
    194         float val;
    195        
     193
    196194#if defined(FLOAT_SIZE_32)
     195
     196#ifndef float32_t
     197        #define float32_t  float
     198#endif
     199
     200#elif defined(FLOAT_SIZE_64)
     201
     202#ifndef float64_t
     203        #define float64_t  float
     204#endif
     205
     206#elif defined(FLOAT_SIZE_96)
     207
     208#ifndef float96_t
     209        #define float96_t  float
     210#endif
     211
     212#elif defined(FLOAT_SIZE_128)
     213
     214#ifndef float128_t
     215        #define float128_t  float
     216#endif
     217
     218#endif
     219
     220
     221#if defined(DOUBLE_SIZE_32)
     222
     223#ifndef float32_t
     224        #define float32_t  double
     225#endif
     226
     227#elif defined(DOUBLE_SIZE_64)
     228
     229#ifndef float64_t
     230        #define float64_t  double
     231#endif
     232
     233#elif defined(DOUBLE_SIZE_96)
     234
     235#ifndef float96_t
     236        #define float96_t  double
     237#endif
     238
     239#elif defined(DOUBLE_SIZE_128)
     240
     241#ifndef float128_t
     242        #define float128_t  double
     243#endif
     244
     245#endif
     246
     247
     248#if defined(LONG_DOUBLE_SIZE_32)
     249
     250#ifndef float32_t
     251        #define float32_t  long double
     252#endif
     253
     254#elif defined(LONG_DOUBLE_SIZE_64)
     255
     256#ifndef float64_t
     257        #define float64_t  long double
     258#endif
     259
     260#elif defined(LONG_DOUBLE_SIZE_96)
     261
     262#ifndef float96_t
     263        #define float96_t  long double
     264#endif
     265
     266#elif defined(LONG_DOUBLE_SIZE_128)
     267
     268#ifndef float128_t
     269        #define float128_t  long double
     270#endif
     271
     272#endif
     273
     274
     275#ifdef float32_t
     276
     277typedef union {
     278        float32_t val;
    197279        float32 data;
    198 #elif defined(FLOAT_SIZE_64)
     280} float32_u;
     281
     282#endif
     283
     284#ifdef float64_t
     285
     286typedef union {
     287        float64_t val;
    199288        float64 data;
    200 #elif defined(FLOAT_SIZE_96)
     289} float64_u;
     290
     291#endif
     292
     293#ifdef float96_t
     294
     295typedef union {
     296        float96_t val;
    201297        float96 data;
    202 #elif defined(FLOAT_SIZE_128)
     298} float96_u;
     299
     300#endif
     301
     302#ifdef float128_t
     303
     304typedef union {
     305        float128_t val;
    203306        float128 data;
    204 #else
    205         #error Unsupported float size
    206 #endif
    207 } float_t;
    208 
    209 typedef union {
    210         double val;
    211        
    212 #if defined(DOUBLE_SIZE_32)
    213         float32 data;
    214 #elif defined(DOUBLE_SIZE_64)
    215         float64 data;
    216 #elif defined(DOUBLE_SIZE_96)
    217         float96 data;
    218 #elif defined(DOUBLE_SIZE_128)
    219         float128 data;
    220 #else
    221         #error Unsupported double size
    222 #endif
    223 } double_t;
    224 
    225 typedef union {
    226         long double val;
    227        
    228 #if defined(LONG_DOUBLE_SIZE_32)
    229         float32 data;
    230 #elif defined(LONG_DOUBLE_SIZE_64)
    231         float64 data;
    232 #elif defined(LONG_DOUBLE_SIZE_96)
    233         float96 data;
    234 #elif defined(LONG_DOUBLE_SIZE_128)
    235         float128 data;
    236 #else
    237         #error Unsupported long double size
    238 #endif
    239 } long_double_t;
     307} float128_u;
     308
     309#endif
    240310
    241311#endif
  • uspace/lib/math/include/mod.h

    r6069061 r58775d30  
    3636#define LIBMATH_MOD_H_
    3737
    38 extern double double_mod(double, double);
     38extern float64_t float64_mod(float64_t, float64_t);
    3939
    4040#endif
  • uspace/lib/math/include/trig.h

    r6069061 r58775d30  
    3636#define LIBMATH_TRIG_H_
    3737
    38 extern double double_sin(double);
    39 extern double double_cos(double);
     38extern float64_t float64_sin(float64_t);
     39extern float64_t float64_cos(float64_t);
    4040
    4141#endif
  • uspace/lib/softfloat/Makefile

    r6069061 r58775d30  
    3333
    3434SOURCES = \
    35         softfloat.c \
    3635        common.c \
    3736        add.c \
     
    3938        div.c \
    4039        mul.c \
     40        neg.c \
    4141        comparison.c \
    4242        conversion.c
  • uspace/lib/softfloat/add.c

    r6069061 r58775d30  
    3434 */
    3535
    36 #include "sftypes.h"
    3736#include "add.h"
    3837#include "comparison.h"
    3938#include "common.h"
     39#include "sub.h"
    4040
    4141/** Add two single-precision floats with the same sign.
     
    413413}
    414414
     415#ifdef float32_t
     416
     417float32_t __addsf3(float32_t a, float32_t b)
     418{
     419        float32_u ua;
     420        ua.val = a;
     421       
     422        float32_u ub;
     423        ub.val = b;
     424       
     425        float32_u res;
     426       
     427        if (ua.data.parts.sign != ub.data.parts.sign) {
     428                if (ua.data.parts.sign) {
     429                        ua.data.parts.sign = 0;
     430                        res.data = sub_float32(ub.data, ua.data);
     431                } else {
     432                        ub.data.parts.sign = 0;
     433                        res.data = sub_float32(ua.data, ub.data);
     434                }
     435        } else
     436                res.data = add_float32(ua.data, ub.data);
     437       
     438        return res.val;
     439}
     440
     441float32_t __aeabi_fadd(float32_t a, float32_t b)
     442{
     443        float32_u ua;
     444        ua.val = a;
     445       
     446        float32_u ub;
     447        ub.val = b;
     448       
     449        float32_u res;
     450       
     451        if (ua.data.parts.sign != ub.data.parts.sign) {
     452                if (ua.data.parts.sign) {
     453                        ua.data.parts.sign = 0;
     454                        res.data = sub_float32(ub.data, ua.data);
     455                } else {
     456                        ub.data.parts.sign = 0;
     457                        res.data = sub_float32(ua.data, ub.data);
     458                }
     459        } else
     460                res.data = add_float32(ua.data, ub.data);
     461       
     462        return res.val;
     463}
     464
     465#endif
     466
     467#ifdef float64_t
     468
     469float64_t __adddf3(float64_t a, float64_t b)
     470{
     471        float64_u ua;
     472        ua.val = a;
     473       
     474        float64_u ub;
     475        ub.val = b;
     476       
     477        float64_u res;
     478       
     479        if (ua.data.parts.sign != ub.data.parts.sign) {
     480                if (ua.data.parts.sign) {
     481                        ua.data.parts.sign = 0;
     482                        res.data = sub_float64(ub.data, ua.data);
     483                } else {
     484                        ub.data.parts.sign = 0;
     485                        res.data = sub_float64(ua.data, ub.data);
     486                }
     487        } else
     488                res.data = add_float64(ua.data, ub.data);
     489       
     490        return res.val;
     491}
     492
     493float64_t __aeabi_dadd(float64_t a, float64_t b)
     494{
     495        float64_u ua;
     496        ua.val = a;
     497       
     498        float64_u ub;
     499        ub.val = b;
     500       
     501        float64_u res;
     502       
     503        if (ua.data.parts.sign != ub.data.parts.sign) {
     504                if (ua.data.parts.sign) {
     505                        ua.data.parts.sign = 0;
     506                        res.data = sub_float64(ub.data, ua.data);
     507                } else {
     508                        ub.data.parts.sign = 0;
     509                        res.data = sub_float64(ua.data, ub.data);
     510                }
     511        } else
     512                res.data = add_float64(ua.data, ub.data);
     513       
     514        return res.val;
     515}
     516
     517#endif
     518
     519#ifdef float128_t
     520
     521float128_t __addtf3(float128_t a, float128_t b)
     522{
     523        float128_u ua;
     524        ua.val = a;
     525       
     526        float128_u ub;
     527        ub.val = b;
     528       
     529        float128_u res;
     530       
     531        if (ua.data.parts.sign != ub.data.parts.sign) {
     532                if (ua.data.parts.sign) {
     533                        ua.data.parts.sign = 0;
     534                        res.data = sub_float128(ub.data, ua.data);
     535                } else {
     536                        ub.data.parts.sign = 0;
     537                        res.data = sub_float128(ua.data, ub.data);
     538                }
     539        } else
     540                res.data = add_float128(ua.data, ub.data);
     541       
     542        return res.val;
     543}
     544
     545void _Qp_add(float128_t *c, float128_t *a, float128_t *b)
     546{
     547        *c = __addtf3(*a, *b);
     548}
     549
     550#endif
     551
    415552/** @}
    416553 */
  • uspace/lib/softfloat/add.h

    r6069061 r58775d30  
    3737#define __ADD_H__
    3838
     39#include <mathtypes.h>
     40
    3941extern float32 add_float32(float32, float32);
    4042extern float64 add_float64(float64, float64);
     
    4244extern float128 add_float128(float128, float128);
    4345
     46#ifdef float32_t
     47extern float32_t __addsf3(float32_t, float32_t);
     48extern float32_t __aeabi_fadd(float32_t, float32_t);
     49#endif
     50
     51#ifdef float64_t
     52extern float64_t __adddf3(float64_t, float64_t);
     53extern float64_t __aeabi_dadd(float64_t, float64_t);
     54#endif
     55
     56#ifdef float128_t
     57extern float128_t __addtf3(float128_t, float128_t);
     58extern void _Qp_add(float128_t *, float128_t *, float128_t *);
     59#endif
     60
    4461#endif
    4562
  • uspace/lib/softfloat/common.c

    r6069061 r58775d30  
    3434 */
    3535
    36 #include "sftypes.h"
    3736#include "common.h"
    3837
  • uspace/lib/softfloat/common.h

    r6069061 r58775d30  
    3737#define __COMMON_H__
    3838
    39 #include "sftypes.h"
     39#include <mathtypes.h>
    4040
    4141extern float64 finish_float64(int32_t, uint64_t, char);
     
    5353extern void rshift128(uint64_t, uint64_t, int, uint64_t *, uint64_t *);
    5454
    55 extern void and128(uint64_t, uint64_t, uint64_t, uint64_t, uint64_t *, uint64_t *);
    56 extern void or128(uint64_t, uint64_t, uint64_t, uint64_t, uint64_t *, uint64_t *);
    57 extern void xor128(uint64_t, uint64_t, uint64_t, uint64_t, uint64_t *, uint64_t *);
     55extern void and128(uint64_t, uint64_t, uint64_t, uint64_t, uint64_t *,
     56    uint64_t *);
     57extern void or128(uint64_t, uint64_t, uint64_t, uint64_t, uint64_t *,
     58    uint64_t *);
     59extern void xor128(uint64_t, uint64_t, uint64_t, uint64_t, uint64_t *,
     60    uint64_t *);
    5861extern void not128(uint64_t, uint64_t, uint64_t *, uint64_t *);
    5962
     
    6265extern int lt128(uint64_t, uint64_t, uint64_t, uint64_t);
    6366
    64 extern void add128(uint64_t, uint64_t, uint64_t, uint64_t, uint64_t *, uint64_t *);
    65 extern void sub128(uint64_t, uint64_t, uint64_t, uint64_t, uint64_t *, uint64_t *);
     67extern void add128(uint64_t, uint64_t, uint64_t, uint64_t, uint64_t *,
     68    uint64_t *);
     69extern void sub128(uint64_t, uint64_t, uint64_t, uint64_t, uint64_t *,
     70    uint64_t *);
    6671
    6772extern void mul64(uint64_t, uint64_t, uint64_t *, uint64_t *);
  • uspace/lib/softfloat/comparison.c

    r6069061 r58775d30  
    3434 */
    3535
    36 #include "sftypes.h"
    3736#include "comparison.h"
    3837#include "common.h"
     
    439438}
    440439
     440#ifdef float32_t
     441
     442int __gtsf2(float32_t a, float32_t b)
     443{
     444        float32_u ua;
     445        ua.val = a;
     446       
     447        float32_u ub;
     448        ub.val = b;
     449       
     450        if ((is_float32_nan(ua.data)) || (is_float32_nan(ub.data))) {
     451                // TODO: sigNaNs
     452                return -1;
     453        }
     454       
     455        if (is_float32_gt(ua.data, ub.data))
     456                return 1;
     457       
     458        return 0;
     459}
     460
     461int __gesf2(float32_t a, float32_t b)
     462{
     463        float32_u ua;
     464        ua.val = a;
     465       
     466        float32_u ub;
     467        ub.val = b;
     468       
     469        if ((is_float32_nan(ua.data)) || (is_float32_nan(ub.data))) {
     470                // TODO: sigNaNs
     471                return -1;
     472        }
     473       
     474        if (is_float32_eq(ua.data, ub.data))
     475                return 0;
     476       
     477        if (is_float32_gt(ua.data, ub.data))
     478                return 1;
     479       
     480        return -1;
     481}
     482
     483int __ltsf2(float32_t a, float32_t b)
     484{
     485        float32_u ua;
     486        ua.val = a;
     487       
     488        float32_u ub;
     489        ub.val = b;
     490       
     491        if ((is_float32_nan(ua.data)) || (is_float32_nan(ub.data))) {
     492                // TODO: sigNaNs
     493                return 1;
     494        }
     495       
     496        if (is_float32_lt(ua.data, ub.data))
     497                return -1;
     498       
     499        return 0;
     500}
     501
     502int __lesf2(float32_t a, float32_t b)
     503{
     504        float32_u ua;
     505        ua.val = a;
     506       
     507        float32_u ub;
     508        ub.val = b;
     509       
     510        if ((is_float32_nan(ua.data)) || (is_float32_nan(ub.data))) {
     511                // TODO: sigNaNs
     512                return 1;
     513        }
     514       
     515        if (is_float32_eq(ua.data, ub.data))
     516                return 0;
     517       
     518        if (is_float32_lt(ua.data, ub.data))
     519                return -1;
     520       
     521        return 1;
     522}
     523
     524int __eqsf2(float32_t a, float32_t b)
     525{
     526        float32_u ua;
     527        ua.val = a;
     528       
     529        float32_u ub;
     530        ub.val = b;
     531       
     532        if ((is_float32_nan(ua.data)) || (is_float32_nan(ub.data))) {
     533                // TODO: sigNaNs
     534                return 1;
     535        }
     536       
     537        return is_float32_eq(ua.data, ub.data) - 1;
     538}
     539
     540int __nesf2(float32_t a, float32_t b)
     541{
     542        /* Strange, but according to GCC documentation */
     543        return __eqsf2(a, b);
     544}
     545
     546int __cmpsf2(float32_t a, float32_t b)
     547{
     548        float32_u ua;
     549        ua.val = a;
     550       
     551        float32_u ub;
     552        ub.val = b;
     553       
     554        if ((is_float32_nan(ua.data)) || (is_float32_nan(ub.data))) {
     555                /* No special constant for unordered - maybe signaled? */
     556                return 1;
     557        }
     558       
     559        if (is_float32_eq(ua.data, ub.data))
     560                return 0;
     561       
     562        if (is_float32_lt(ua.data, ub.data))
     563                return -1;
     564       
     565        return 1;
     566}
     567
     568int __unordsf2(float32_t a, float32_t b)
     569{
     570        float32_u ua;
     571        ua.val = a;
     572       
     573        float32_u ub;
     574        ub.val = b;
     575       
     576        return ((is_float32_nan(ua.data)) || (is_float32_nan(ub.data)));
     577}
     578
     579int __aeabi_fcmpgt(float32_t a, float32_t b)
     580{
     581        float32_u ua;
     582        ua.val = a;
     583       
     584        float32_u ub;
     585        ub.val = b;
     586       
     587        if ((is_float32_nan(ua.data)) || (is_float32_nan(ub.data))) {
     588                // TODO: sigNaNs
     589                return -1;
     590        }
     591       
     592        if (is_float32_gt(ua.data, ub.data))
     593                return 1;
     594       
     595        return 0;
     596}
     597
     598int __aeabi_fcmplt(float32_t a, float32_t b)
     599{
     600        float32_u ua;
     601        ua.val = a;
     602       
     603        float32_u ub;
     604        ub.val = b;
     605       
     606        if ((is_float32_nan(ua.data)) || (is_float32_nan(ub.data))) {
     607                // TODO: sigNaNs
     608                return 1;
     609        }
     610       
     611        if (is_float32_lt(ua.data, ub.data))
     612                return -1;
     613       
     614        return 0;
     615}
     616
     617int __aeabi_fcmpge(float32_t a, float32_t b)
     618{
     619        float32_u ua;
     620        ua.val = a;
     621       
     622        float32_u ub;
     623        ub.val = b;
     624       
     625        if ((is_float32_nan(ua.data)) || (is_float32_nan(ub.data))) {
     626                // TODO: sigNaNs
     627                return -1;
     628        }
     629       
     630        if (is_float32_eq(ua.data, ub.data))
     631                return 0;
     632       
     633        if (is_float32_gt(ua.data, ub.data))
     634                return 1;
     635       
     636        return -1;
     637}
     638
     639int __aeabi_fcmpeq(float32_t a, float32_t b)
     640{
     641        float32_u ua;
     642        ua.val = a;
     643       
     644        float32_u ub;
     645        ub.val = b;
     646       
     647        if ((is_float32_nan(ua.data)) || (is_float32_nan(ub.data))) {
     648                // TODO: sigNaNs
     649                return 1;
     650        }
     651       
     652        return is_float32_eq(ua.data, ub.data) - 1;
     653}
     654
     655#endif
     656
     657#ifdef float64_t
     658
     659int __gtdf2(float64_t a, float64_t b)
     660{
     661        float64_u ua;
     662        ua.val = a;
     663       
     664        float64_u ub;
     665        ub.val = b;
     666       
     667        if ((is_float64_nan(ua.data)) || (is_float64_nan(ub.data))) {
     668                // TODO: sigNaNs
     669                return -1;
     670        }
     671       
     672        if (is_float64_gt(ua.data, ub.data))
     673                return 1;
     674       
     675        return 0;
     676}
     677
     678int __gedf2(float64_t a, float64_t b)
     679{
     680        float64_u ua;
     681        ua.val = a;
     682       
     683        float64_u ub;
     684        ub.val = b;
     685       
     686        if ((is_float64_nan(ua.data)) || (is_float64_nan(ub.data))) {
     687                // TODO: sigNaNs
     688                return -1;
     689        }
     690       
     691        if (is_float64_eq(ua.data, ub.data))
     692                return 0;
     693       
     694        if (is_float64_gt(ua.data, ub.data))
     695                return 1;
     696       
     697        return -1;
     698}
     699
     700int __ltdf2(float64_t a, float64_t b)
     701{
     702        float64_u ua;
     703        ua.val = a;
     704       
     705        float64_u ub;
     706        ub.val = b;
     707       
     708        if ((is_float64_nan(ua.data)) || (is_float64_nan(ub.data))) {
     709                // TODO: sigNaNs
     710                return 1;
     711        }
     712       
     713        if (is_float64_lt(ua.data, ub.data))
     714                return -1;
     715       
     716        return 0;
     717}
     718
     719int __ledf2(float64_t a, float64_t b)
     720{
     721        float64_u ua;
     722        ua.val = a;
     723       
     724        float64_u ub;
     725        ub.val = b;
     726       
     727        if ((is_float64_nan(ua.data)) || (is_float64_nan(ub.data))) {
     728                // TODO: sigNaNs
     729                return 1;
     730        }
     731       
     732        if (is_float64_eq(ua.data, ub.data))
     733                return 0;
     734       
     735        if (is_float64_lt(ua.data, ub.data))
     736                return -1;
     737       
     738        return 1;
     739}
     740
     741int __eqdf2(float64_t a, float64_t b)
     742{
     743        float64_u ua;
     744        ua.val = a;
     745       
     746        float64_u ub;
     747        ub.val = b;
     748       
     749        if ((is_float64_nan(ua.data)) || (is_float64_nan(ub.data))) {
     750                // TODO: sigNaNs
     751                return 1;
     752        }
     753       
     754        return is_float64_eq(ua.data, ub.data) - 1;
     755}
     756
     757int __nedf2(float64_t a, float64_t b)
     758{
     759        /* Strange, but according to GCC documentation */
     760        return __eqdf2(a, b);
     761}
     762
     763int __cmpdf2(float64_t a, float64_t b)
     764{
     765        float64_u ua;
     766        ua.val = a;
     767       
     768        float64_u ub;
     769        ub.val = b;
     770       
     771        if ((is_float64_nan(ua.data)) || (is_float64_nan(ub.data))) {
     772                /* No special constant for unordered - maybe signaled? */
     773                return 1;
     774        }
     775       
     776        if (is_float64_eq(ua.data, ub.data))
     777                return 0;
     778       
     779        if (is_float64_lt(ua.data, ub.data))
     780                return -1;
     781       
     782        return 1;
     783}
     784
     785int __unorddf2(float64_t a, float64_t b)
     786{
     787        float64_u ua;
     788        ua.val = a;
     789       
     790        float64_u ub;
     791        ub.val = b;
     792       
     793        return ((is_float64_nan(ua.data)) || (is_float64_nan(ub.data)));
     794}
     795
     796int __aeabi_dcmplt(float64_t a, float64_t b)
     797{
     798        float64_u ua;
     799        ua.val = a;
     800       
     801        float64_u ub;
     802        ub.val = b;
     803       
     804        if ((is_float64_nan(ua.data)) || (is_float64_nan(ub.data))) {
     805                // TODO: sigNaNs
     806                return 1;
     807        }
     808       
     809        if (is_float64_lt(ua.data, ub.data))
     810                return -1;
     811       
     812        return 0;
     813}
     814
     815int __aeabi_dcmpeq(float64_t a, float64_t b)
     816{
     817        float64_u ua;
     818        ua.val = a;
     819       
     820        float64_u ub;
     821        ub.val = b;
     822       
     823        if ((is_float64_nan(ua.data)) || (is_float64_nan(ub.data))) {
     824                // TODO: sigNaNs
     825                return 1;
     826        }
     827       
     828        return is_float64_eq(ua.data, ub.data) - 1;
     829}
     830
     831int __aeabi_dcmpgt(float64_t a, float64_t b)
     832{
     833        float64_u ua;
     834        ua.val = a;
     835       
     836        float64_u ub;
     837        ub.val = b;
     838       
     839        if ((is_float64_nan(ua.data)) || (is_float64_nan(ub.data))) {
     840                // TODO: sigNaNs
     841                return -1;
     842        }
     843       
     844        if (is_float64_gt(ua.data, ub.data))
     845                return 1;
     846       
     847        return 0;
     848}
     849
     850int __aeabi_dcmpge(float64_t a, float64_t b)
     851{
     852        float64_u ua;
     853        ua.val = a;
     854       
     855        float64_u ub;
     856        ub.val = b;
     857       
     858        if ((is_float64_nan(ua.data)) || (is_float64_nan(ub.data))) {
     859                // TODO: sigNaNs
     860                return -1;
     861        }
     862       
     863        if (is_float64_eq(ua.data, ub.data))
     864                return 0;
     865       
     866        if (is_float64_gt(ua.data, ub.data))
     867                return 1;
     868       
     869        return -1;
     870}
     871
     872int __aeabi_dcmple(float64_t a, float64_t b)
     873{
     874        float64_u ua;
     875        ua.val = a;
     876       
     877        float64_u ub;
     878        ub.val = b;
     879       
     880        if ((is_float64_nan(ua.data)) || (is_float64_nan(ub.data))) {
     881                // TODO: sigNaNs
     882                return 1;
     883        }
     884       
     885        if (is_float64_eq(ua.data, ub.data))
     886                return 0;
     887       
     888        if (is_float64_lt(ua.data, ub.data))
     889                return -1;
     890       
     891        return 1;
     892}
     893
     894#endif
     895
     896#ifdef float128_t
     897
     898int __gttf2(float128_t a, float128_t b)
     899{
     900        float128_u ua;
     901        ua.val = a;
     902       
     903        float128_u ub;
     904        ub.val = b;
     905       
     906        if ((is_float128_nan(ua.data)) || (is_float128_nan(ub.data))) {
     907                // TODO: sigNaNs
     908                return -1;
     909        }
     910       
     911        if (is_float128_gt(ua.data, ub.data))
     912                return 1;
     913       
     914        return 0;
     915}
     916
     917int __getf2(float128_t a, float128_t b)
     918{
     919        float128_u ua;
     920        ua.val = a;
     921       
     922        float128_u ub;
     923        ub.val = b;
     924       
     925        if ((is_float128_nan(ua.data)) || (is_float128_nan(ub.data))) {
     926                // TODO: sigNaNs
     927                return -1;
     928        }
     929       
     930        if (is_float128_eq(ua.data, ub.data))
     931                return 0;
     932       
     933        if (is_float128_gt(ua.data, ub.data))
     934                return 1;
     935       
     936        return -1;
     937}
     938
     939int __lttf2(float128_t a, float128_t b)
     940{
     941        float128_u ua;
     942        ua.val = a;
     943       
     944        float128_u ub;
     945        ub.val = b;
     946       
     947        if ((is_float128_nan(ua.data)) || (is_float128_nan(ub.data))) {
     948                // TODO: sigNaNs
     949                return 1;
     950        }
     951       
     952        if (is_float128_lt(ua.data, ub.data))
     953                return -1;
     954       
     955        return 0;
     956}
     957
     958int __letf2(float128_t a, float128_t b)
     959{
     960        float128_u ua;
     961        ua.val = a;
     962       
     963        float128_u ub;
     964        ub.val = b;
     965       
     966        if ((is_float128_nan(ua.data)) || (is_float128_nan(ub.data))) {
     967                // TODO: sigNaNs
     968                return 1;
     969        }
     970       
     971        if (is_float128_eq(ua.data, ub.data))
     972                return 0;
     973       
     974        if (is_float128_lt(ua.data, ub.data))
     975                return -1;
     976       
     977        return 1;
     978}
     979
     980int __eqtf2(float128_t a, float128_t b)
     981{
     982        float128_u ua;
     983        ua.val = a;
     984       
     985        float128_u ub;
     986        ub.val = b;
     987       
     988        if ((is_float128_nan(ua.data)) || (is_float128_nan(ub.data))) {
     989                // TODO: sigNaNs
     990                return 1;
     991        }
     992       
     993        return is_float128_eq(ua.data, ub.data) - 1;
     994}
     995
     996int __netf2(float128_t a, float128_t b)
     997{
     998        /* Strange, but according to GCC documentation */
     999        return __eqtf2(a, b);
     1000}
     1001
     1002int __cmptf2(float128_t a, float128_t b)
     1003{
     1004        float128_u ua;
     1005        ua.val = a;
     1006       
     1007        float128_u ub;
     1008        ub.val = b;
     1009       
     1010        if ((is_float128_nan(ua.data)) || (is_float128_nan(ub.data))) {
     1011                /* No special constant for unordered - maybe signaled? */
     1012                return 1;
     1013        }
     1014       
     1015        if (is_float128_eq(ua.data, ub.data))
     1016                return 0;
     1017       
     1018        if (is_float128_lt(ua.data, ub.data))
     1019                return -1;
     1020       
     1021        return 1;
     1022}
     1023
     1024int __unordtf2(float128_t a, float128_t b)
     1025{
     1026        float128_u ua;
     1027        ua.val = a;
     1028       
     1029        float128_u ub;
     1030        ub.val = b;
     1031       
     1032        return ((is_float128_nan(ua.data)) || (is_float128_nan(ub.data)));
     1033}
     1034
     1035int _Qp_cmp(float128_t *a, float128_t *b)
     1036{
     1037        float128_u ua;
     1038        ua.val = *a;
     1039       
     1040        float128_u ub;
     1041        ub.val = *b;
     1042       
     1043        if ((is_float128_nan(ua.data)) || (is_float128_nan(ub.data)))
     1044                return 3;
     1045       
     1046        if (is_float128_eq(ua.data, ub.data))
     1047                return 0;
     1048       
     1049        if (is_float128_lt(ua.data, ub.data))
     1050                return 1;
     1051       
     1052        return 2;
     1053}
     1054
     1055int _Qp_cmpe(float128_t *a, float128_t *b)
     1056{
     1057        /* Strange, but according to SPARC Compliance Definition */
     1058        return _Qp_cmp(a, b);
     1059}
     1060
     1061int _Qp_fgt(float128_t *a, float128_t *b)
     1062{
     1063        float128_u ua;
     1064        ua.val = *a;
     1065       
     1066        float128_u ub;
     1067        ub.val = *b;
     1068       
     1069        if ((is_float128_nan(ua.data)) || (is_float128_nan(ub.data)))
     1070                return 0;
     1071       
     1072        return is_float128_gt(ua.data, ub.data);
     1073}
     1074
     1075int _Qp_fge(float128_t *a, float128_t *b)
     1076{
     1077        float128_u ua;
     1078        ua.val = *a;
     1079       
     1080        float128_u ub;
     1081        ub.val = *b;
     1082       
     1083        if ((is_float128_nan(ua.data)) || (is_float128_nan(ub.data)))
     1084                return 0;
     1085       
     1086        return is_float128_eq(ua.data, ub.data) ||
     1087            is_float128_gt(ua.data, ub.data);
     1088}
     1089
     1090int _Qp_flt(float128_t *a, float128_t *b)
     1091{
     1092        float128_u ua;
     1093        ua.val = *a;
     1094       
     1095        float128_u ub;
     1096        ub.val = *b;
     1097       
     1098        if ((is_float128_nan(ua.data)) || (is_float128_nan(ub.data)))
     1099                return 0;
     1100       
     1101        return is_float128_lt(ua.data, ub.data);
     1102}
     1103
     1104int _Qp_fle(float128_t *a, float128_t *b)
     1105{
     1106        float128_u ua;
     1107        ua.val = *a;
     1108       
     1109        float128_u ub;
     1110        ub.val = *b;
     1111       
     1112        if ((is_float128_nan(ua.data)) || (is_float128_nan(ub.data)))
     1113                return 0;
     1114       
     1115        return is_float128_eq(ua.data, ub.data) ||
     1116            is_float128_lt(ua.data, ub.data);
     1117}
     1118
     1119int _Qp_feq(float128_t *a, float128_t *b)
     1120{
     1121        float128_u ua;
     1122        ua.val = *a;
     1123       
     1124        float128_u ub;
     1125        ub.val = *b;
     1126       
     1127        if ((is_float128_nan(ua.data)) || (is_float128_nan(ub.data)))
     1128                return 0;
     1129       
     1130        return is_float128_eq(ua.data, ub.data);
     1131}
     1132
     1133int _Qp_fne(float128_t *a, float128_t *b)
     1134{
     1135        float128_u ua;
     1136        ua.val = *a;
     1137       
     1138        float128_u ub;
     1139        ub.val = *b;
     1140       
     1141        if ((is_float128_nan(ua.data)) || (is_float128_nan(ub.data)))
     1142                return 0;
     1143       
     1144        return !is_float128_eq(ua.data, ub.data);
     1145}
     1146
     1147#endif
     1148
    4411149/** @}
    4421150 */
  • uspace/lib/softfloat/comparison.h

    r6069061 r58775d30  
    3636#ifndef __COMPARISON_H__
    3737#define __COMPARISON_H__
     38
     39#include <mathtypes.h>
    3840
    3941extern int is_float32_nan(float32);
     
    7779extern int is_float128_gt(float128, float128);
    7880
     81#ifdef float32_t
     82extern int __gtsf2(float32_t, float32_t);
     83extern int __gesf2(float32_t, float32_t);
     84extern int __ltsf2(float32_t, float32_t);
     85extern int __lesf2(float32_t, float32_t);
     86extern int __eqsf2(float32_t, float32_t);
     87extern int __nesf2(float32_t, float32_t);
     88extern int __cmpsf2(float32_t, float32_t);
     89extern int __unordsf2(float32_t, float32_t);
     90extern int __aeabi_fcmpgt(float32_t, float32_t);
     91extern int __aeabi_fcmplt(float32_t, float32_t);
     92extern int __aeabi_fcmpge(float32_t, float32_t);
     93extern int __aeabi_fcmpeq(float32_t, float32_t);
     94#endif
     95
     96#ifdef float64_t
     97extern int __gtdf2(float64_t, float64_t);
     98extern int __gedf2(float64_t, float64_t);
     99extern int __ltdf2(float64_t, float64_t);
     100extern int __ledf2(float64_t, float64_t);
     101extern int __eqdf2(float64_t, float64_t);
     102extern int __nedf2(float64_t, float64_t);
     103extern int __cmpdf2(float64_t, float64_t);
     104extern int __unorddf2(float64_t, float64_t);
     105extern int __aeabi_dcmplt(float64_t, float64_t);
     106extern int __aeabi_dcmpeq(float64_t, float64_t);
     107extern int __aeabi_dcmpgt(float64_t, float64_t);
     108extern int __aeabi_dcmpge(float64_t, float64_t);
     109extern int __aeabi_dcmple(float64_t, float64_t);
     110#endif
     111
     112#ifdef float128_t
     113extern int __gttf2(float128_t, float128_t);
     114extern int __getf2(float128_t, float128_t);
     115extern int __lttf2(float128_t, float128_t);
     116extern int __letf2(float128_t, float128_t);
     117extern int __eqtf2(float128_t, float128_t);
     118extern int __netf2(float128_t, float128_t);
     119extern int __cmptf2(float128_t, float128_t);
     120extern int __unordtf2(float128_t, float128_t);
     121extern int _Qp_cmp(float128_t *, float128_t *);
     122extern int _Qp_cmpe(float128_t *, float128_t *);
     123extern int _Qp_fgt(float128_t *, float128_t *);
     124extern int _Qp_fge(float128_t *, float128_t *);
     125extern int _Qp_flt(float128_t *, float128_t *);
     126extern int _Qp_fle(float128_t *, float128_t *);
     127extern int _Qp_feq(float128_t *, float128_t *);
     128extern int _Qp_fne(float128_t *, float128_t *);
     129
     130#endif
     131
    79132#endif
    80133
  • uspace/lib/softfloat/conversion.c

    r6069061 r58775d30  
    3434 */
    3535
    36 #include "sftypes.h"
    3736#include "conversion.h"
    3837#include "comparison.h"
     
    10371036}
    10381037
     1038#ifdef float32_t
     1039
     1040float32_t __floatsisf(int32_t i)
     1041{
     1042        float32_u res;
     1043        res.data = int32_to_float32(i);
     1044       
     1045        return res.val;
     1046}
     1047
     1048float32_t __floatdisf(int64_t i)
     1049{
     1050        float32_u res;
     1051        res.data = int64_to_float32(i);
     1052       
     1053        return res.val;
     1054}
     1055
     1056float32_t __floatunsisf(uint32_t i)
     1057{
     1058        float32_u res;
     1059        res.data = uint32_to_float32(i);
     1060       
     1061        return res.val;
     1062}
     1063
     1064float32_t __floatundisf(uint64_t i)
     1065{
     1066        float32_u res;
     1067        res.data = uint64_to_float32(i);
     1068       
     1069        return res.val;
     1070}
     1071
     1072int32_t __fixsfsi(float32_t a)
     1073{
     1074        float32_u ua;
     1075        ua.val = a;
     1076       
     1077        return float32_to_int32(ua.data);
     1078}
     1079
     1080int64_t __fixsfdi(float32_t a)
     1081{
     1082        float32_u ua;
     1083        ua.val = a;
     1084       
     1085        return float32_to_int64(ua.data);
     1086}
     1087
     1088uint32_t __fixunssfsi(float32_t a)
     1089{
     1090        float32_u ua;
     1091        ua.val = a;
     1092       
     1093        return float32_to_uint32(ua.data);
     1094}
     1095
     1096uint64_t __fixunssfdi(float32_t a)
     1097{
     1098        float32_u ua;
     1099        ua.val = a;
     1100       
     1101        return float32_to_uint64(ua.data);
     1102}
     1103
     1104int32_t __aeabi_f2iz(float32_t a)
     1105{
     1106        float32_u ua;
     1107        ua.val = a;
     1108       
     1109        return float32_to_int32(ua.data);
     1110}
     1111
     1112uint32_t __aeabi_f2uiz(float32_t a)
     1113{
     1114        float32_u ua;
     1115        ua.val = a;
     1116       
     1117        return float32_to_uint32(ua.data);
     1118}
     1119
     1120float32_t __aeabi_i2f(int32_t i)
     1121{
     1122        float32_u res;
     1123        res.data = int32_to_float32(i);
     1124       
     1125        return res.val;
     1126}
     1127
     1128float32_t __aeabi_l2f(int64_t i)
     1129{
     1130        float32_u res;
     1131        res.data = int64_to_float32(i);
     1132       
     1133        return res.val;
     1134}
     1135
     1136float32_t __aeabi_ui2f(uint32_t i)
     1137{
     1138        float32_u res;
     1139        res.data = uint32_to_float32(i);
     1140       
     1141        return res.val;
     1142}
     1143
     1144float32_t __aeabi_ul2f(uint64_t i)
     1145{
     1146        float32_u res;
     1147        res.data = uint64_to_float32(i);
     1148       
     1149        return res.val;
     1150}
     1151
     1152#endif
     1153
     1154#ifdef float64_t
     1155
     1156float64_t __floatsidf(int32_t i)
     1157{
     1158        float64_u res;
     1159        res.data = int32_to_float64(i);
     1160       
     1161        return res.val;
     1162}
     1163
     1164float64_t __floatdidf(int64_t i)
     1165{
     1166        float64_u res;
     1167        res.data = int64_to_float64(i);
     1168       
     1169        return res.val;
     1170}
     1171
     1172float64_t __floatunsidf(uint32_t i)
     1173{
     1174        float64_u res;
     1175        res.data = uint32_to_float64(i);
     1176       
     1177        return res.val;
     1178}
     1179
     1180float64_t __floatundidf(uint64_t i)
     1181{
     1182        float64_u res;
     1183        res.data = uint64_to_float64(i);
     1184       
     1185        return res.val;
     1186}
     1187
     1188uint32_t __fixunsdfsi(float64_t a)
     1189{
     1190        float64_u ua;
     1191        ua.val = a;
     1192       
     1193        return float64_to_uint32(ua.data);
     1194}
     1195
     1196uint64_t __fixunsdfdi(float64_t a)
     1197{
     1198        float64_u ua;
     1199        ua.val = a;
     1200       
     1201        return float64_to_uint64(ua.data);
     1202}
     1203
     1204int32_t __fixdfsi(float64_t a)
     1205{
     1206        float64_u ua;
     1207        ua.val = a;
     1208       
     1209        return float64_to_int32(ua.data);
     1210}
     1211
     1212int64_t __fixdfdi(float64_t a)
     1213{
     1214        float64_u ua;
     1215        ua.val = a;
     1216       
     1217        return float64_to_int64(ua.data);
     1218}
     1219
     1220float64_t __aeabi_i2d(int32_t i)
     1221{
     1222        float64_u res;
     1223        res.data = int32_to_float64(i);
     1224       
     1225        return res.val;
     1226}
     1227
     1228float64_t __aeabi_ui2d(uint32_t i)
     1229{
     1230        float64_u res;
     1231        res.data = uint32_to_float64(i);
     1232       
     1233        return res.val;
     1234}
     1235
     1236float64_t __aeabi_l2d(int64_t i)
     1237{
     1238        float64_u res;
     1239        res.data = int64_to_float64(i);
     1240       
     1241        return res.val;
     1242}
     1243
     1244int32_t __aeabi_d2iz(float64_t a)
     1245{
     1246        float64_u ua;
     1247        ua.val = a;
     1248       
     1249        return float64_to_int32(ua.data);
     1250}
     1251
     1252int64_t __aeabi_d2lz(float64_t a)
     1253{
     1254        float64_u ua;
     1255        ua.val = a;
     1256       
     1257        return float64_to_int64(ua.data);
     1258}
     1259
     1260uint32_t __aeabi_d2uiz(float64_t a)
     1261{
     1262        float64_u ua;
     1263        ua.val = a;
     1264       
     1265        return float64_to_uint32(ua.data);
     1266}
     1267
     1268#endif
     1269
     1270#ifdef float128_t
     1271
     1272float128_t __floatsitf(int32_t i)
     1273{
     1274        float128_u res;
     1275        res.data = int32_to_float128(i);
     1276       
     1277        return res.val;
     1278}
     1279
     1280float128_t __floatditf(int64_t i)
     1281{
     1282        float128_u res;
     1283        res.data = int64_to_float128(i);
     1284       
     1285        return res.val;
     1286}
     1287
     1288float128_t __floatunsitf(uint32_t i)
     1289{
     1290        float128_u res;
     1291        res.data = uint32_to_float128(i);
     1292       
     1293        return res.val;
     1294}
     1295
     1296float128_t __floatunditf(uint64_t i)
     1297{
     1298        float128_u res;
     1299        res.data = uint64_to_float128(i);
     1300       
     1301        return res.val;
     1302}
     1303
     1304int32_t __fixtfsi(float128_t a)
     1305{
     1306        float128_u ua;
     1307        ua.val = a;
     1308       
     1309        return float128_to_int32(ua.data);
     1310}
     1311
     1312int64_t __fixtfdi(float128_t a)
     1313{
     1314        float128_u ua;
     1315        ua.val = a;
     1316       
     1317        return float128_to_uint64(ua.data);
     1318}
     1319
     1320uint32_t __fixunstfsi(float128_t a)
     1321{
     1322        float128_u ua;
     1323        ua.val = a;
     1324       
     1325        return float128_to_uint32(ua.data);
     1326}
     1327
     1328uint64_t __fixunstfdi(float128_t a)
     1329{
     1330        float128_u ua;
     1331        ua.val = a;
     1332       
     1333        return float128_to_uint64(ua.data);
     1334}
     1335
     1336int32_t _Qp_qtoi(float128_t *a)
     1337{
     1338        return __fixtfsi(*a);
     1339}
     1340
     1341int64_t _Qp_qtox(float128_t *a)
     1342{
     1343        return __fixunstfdi(*a);
     1344}
     1345
     1346uint32_t _Qp_qtoui(float128_t *a)
     1347{
     1348        return __fixunstfsi(*a);
     1349}
     1350
     1351uint64_t _Qp_qtoux(float128_t *a)
     1352{
     1353        return __fixunstfdi(*a);
     1354}
     1355
     1356void _Qp_itoq(float128_t *c, int32_t a)
     1357{
     1358        *c = __floatsitf(a);
     1359}
     1360
     1361void _Qp_xtoq(float128_t *c, int64_t a)
     1362{
     1363        *c = __floatditf(a);
     1364}
     1365
     1366void _Qp_uitoq(float128_t *c, uint32_t a)
     1367{
     1368        *c = __floatunsitf(a);
     1369}
     1370
     1371void _Qp_uxtoq(float128_t *c, uint64_t a)
     1372{
     1373        *c = __floatunditf(a);
     1374}
     1375
     1376#endif
     1377
     1378#if (defined(float32_t) && defined(float64_t))
     1379
     1380float32_t __truncdfsf2(float64_t a)
     1381{
     1382        float64_u ua;
     1383        ua.val = a;
     1384       
     1385        float32_u res;
     1386        res.data = float64_to_float32(ua.data);
     1387       
     1388        return res.val;
     1389}
     1390
     1391float64_t __extendsfdf2(float32_t a)
     1392{
     1393        float32_u ua;
     1394        ua.val = a;
     1395       
     1396        float64_u res;
     1397        res.data = float32_to_float64(ua.data);
     1398       
     1399        return res.val;
     1400}
     1401
     1402float64_t __aeabi_f2d(float32_t a)
     1403{
     1404        float32_u ua;
     1405        ua.val = a;
     1406       
     1407        float64_u res;
     1408        res.data = float32_to_float64(ua.data);
     1409       
     1410        return res.val;
     1411}
     1412
     1413float32_t __aeabi_d2f(float64_t a)
     1414{
     1415        float64_u ua;
     1416        ua.val = a;
     1417       
     1418        float32_u res;
     1419        res.data = float64_to_float32(ua.data);
     1420       
     1421        return res.val;
     1422}
     1423
     1424#endif
     1425
     1426#if (defined(float32_t) && defined(float128_t))
     1427
     1428float32_t __trunctfsf2(float128_t a)
     1429{
     1430        float128_u ua;
     1431        ua.val = a;
     1432       
     1433        float32_u res;
     1434        res.data = float128_to_float32(ua.data);
     1435       
     1436        return res.val;
     1437}
     1438
     1439float128_t __extendsftf2(float32_t a)
     1440{
     1441        float32_u ua;
     1442        ua.val = a;
     1443       
     1444        float128_u res;
     1445        res.data = float32_to_float128(ua.data);
     1446       
     1447        return res.val;
     1448}
     1449
     1450void _Qp_stoq(float128_t *c, float32_t a)
     1451{
     1452        *c = __extendsftf2(a);
     1453}
     1454
     1455float32_t _Qp_qtos(float128_t *a)
     1456{
     1457        return __trunctfsf2(*a);
     1458}
     1459
     1460#endif
     1461
     1462#if (defined(float64_t) && defined(float128_t))
     1463
     1464float64_t __trunctfdf2(float128_t a)
     1465{
     1466        float128_u ua;
     1467        ua.val = a;
     1468       
     1469        float64_u res;
     1470        res.data = float128_to_float64(ua.data);
     1471       
     1472        return res.val;
     1473}
     1474
     1475float128_t __extenddftf2(float64_t a)
     1476{
     1477        float64_u ua;
     1478        ua.val = a;
     1479       
     1480        float128_u res;
     1481        res.data = float64_to_float128(ua.data);
     1482       
     1483        return res.val;
     1484}
     1485
     1486void _Qp_dtoq(float128_t *c, float64_t a)
     1487{
     1488        *c = __extenddftf2(a);
     1489}
     1490
     1491float64_t _Qp_qtod(float128_t *a)
     1492{
     1493        return __trunctfdf2(*a);
     1494}
     1495
     1496#endif
     1497
    10391498/** @}
    10401499 */
  • uspace/lib/softfloat/conversion.h

    r6069061 r58775d30  
    3636#ifndef __CONVERSION_H__
    3737#define __CONVERSION_H__
     38
     39#include <mathtypes.h>
    3840
    3941extern float64 float32_to_float64(float32);
     
    99101extern float128 int64_to_float128(int64_t);
    100102
     103#ifdef float32_t
     104extern float32_t __floatsisf(int32_t);
     105extern float32_t __floatdisf(int64_t);
     106extern float32_t __floatunsisf(uint32_t);
     107extern float32_t __floatundisf(uint64_t);
     108extern int32_t __fixsfsi(float32_t);
     109extern int64_t __fixsfdi(float32_t);
     110extern uint32_t __fixunssfsi(float32_t);
     111extern uint64_t __fixunssfdi(float32_t);
     112extern int32_t __aeabi_f2iz(float32_t);
     113extern uint32_t __aeabi_f2uiz(float32_t);
     114extern float32_t __aeabi_i2f(int32_t);
     115extern float32_t __aeabi_l2f(int64_t);
     116extern float32_t __aeabi_ui2f(uint32_t);
     117extern float32_t __aeabi_ul2f(uint64_t);
     118#endif
     119
     120#ifdef float64_t
     121extern float64_t __floatsidf(int32_t);
     122extern float64_t __floatdidf(int64_t);
     123extern float64_t __floatunsidf(uint32_t);
     124extern float64_t __floatundidf(uint64_t);
     125extern int32_t __fixdfsi(float64_t);
     126extern int64_t __fixdfdi(float64_t);
     127extern uint32_t __fixunsdfsi(float64_t);
     128extern uint64_t __fixunsdfdi(float64_t);
     129extern float64_t __aeabi_i2d(int32_t);
     130extern float64_t __aeabi_ui2d(uint32_t);
     131extern float64_t __aeabi_l2d(int64_t);
     132extern int32_t __aeabi_d2iz(float64_t);
     133extern int64_t __aeabi_d2lz(float64_t);
     134extern uint32_t __aeabi_d2uiz(float64_t);
     135#endif
     136
     137#ifdef float128_t
     138extern float128_t __floatsitf(int32_t);
     139extern float128_t __floatditf(int64_t);
     140extern float128_t __floatunsitf(uint32_t);
     141extern float128_t __floatunditf(uint64_t);
     142extern int32_t __fixtfsi(float128_t);
     143extern int64_t __fixtfdi(float128_t);
     144extern uint32_t __fixunstfsi(float128_t);
     145extern uint64_t __fixunstfdi(float128_t);
     146extern int32_t _Qp_qtoi(float128_t *);
     147extern int64_t _Qp_qtox(float128_t *);
     148extern uint32_t _Qp_qtoui(float128_t *);
     149extern uint64_t _Qp_qtoux(float128_t *);
     150extern void _Qp_itoq(float128_t *, int32_t);
     151extern void _Qp_xtoq(float128_t *, int64_t);
     152extern void _Qp_uitoq(float128_t *, uint32_t);
     153extern void _Qp_uxtoq(float128_t *, uint64_t);
     154#endif
     155
     156#if (defined(float32_t) && defined(float64_t))
     157extern float32_t __truncdfsf2(float64_t);
     158extern float64_t __extendsfdf2(float32_t);
     159extern float64_t __aeabi_f2d(float32_t);
     160extern float32_t __aeabi_d2f(float64_t);
     161#endif
     162
     163#if (defined(float32_t) && defined(float128_t))
     164extern float32_t __trunctfsf2(float128_t);
     165extern float128_t __extendsftf2(float32_t);
     166extern void _Qp_stoq(float128_t *, float32_t);
     167extern float32_t _Qp_qtos(float128_t *);
     168#endif
     169
     170#if (defined(float64_t) && defined(float128_t))
     171extern float64_t __trunctfdf2(float128_t);
     172extern float128_t __extenddftf2(float64_t);
     173extern void _Qp_dtoq(float128_t *, float64_t);
     174extern float64_t _Qp_qtod(float128_t *);
     175#endif
     176
    101177#endif
    102178
  • uspace/lib/softfloat/div.c

    r6069061 r58775d30  
    3434 */
    3535
    36 #include "sftypes.h"
    3736#include "add.h"
    3837#include "div.h"
     
    539538}
    540539
     540#ifdef float32_t
     541
     542float32_t __divsf3(float32_t a, float32_t b)
     543{
     544        float32_u ua;
     545        ua.val = a;
     546       
     547        float32_u ub;
     548        ub.val = b;
     549       
     550        float32_u res;
     551        res.data = div_float32(ua.data, ub.data);
     552       
     553        return res.val;
     554}
     555
     556float32_t __aeabi_fdiv(float32_t a, float32_t b)
     557{
     558        float32_u ua;
     559        ua.val = a;
     560       
     561        float32_u ub;
     562        ub.val = b;
     563       
     564        float32_u res;
     565        res.data = div_float32(ua.data, ub.data);
     566       
     567        return res.val;
     568}
     569
     570#endif
     571
     572#ifdef float64_t
     573
     574float64_t __divdf3(float64_t a, float64_t b)
     575{
     576        float64_u ua;
     577        ua.val = a;
     578       
     579        float64_u ub;
     580        ub.val = b;
     581       
     582        float64_u res;
     583        res.data = div_float64(ua.data, ub.data);
     584       
     585        return res.val;
     586}
     587
     588float64_t __aeabi_ddiv(float64_t a, float64_t b)
     589{
     590        float64_u ua;
     591        ua.val = a;
     592       
     593        float64_u ub;
     594        ub.val = b;
     595       
     596        float64_u res;
     597        res.data = div_float64(ua.data, ub.data);
     598       
     599        return res.val;
     600}
     601
     602#endif
     603
     604#ifdef float128_t
     605
     606float128_t __divtf3(float128_t a, float128_t b)
     607{
     608        float128_u ua;
     609        ua.val = a;
     610       
     611        float128_u ub;
     612        ub.val = b;
     613       
     614        float128_u res;
     615        res.data = div_float128(ua.data, ub.data);
     616       
     617        return res.val;
     618}
     619
     620void _Qp_div(float128_t *c, float128_t *a, float128_t *b)
     621{
     622        *c = __divtf3(*a, *b);
     623}
     624
     625#endif
     626
    541627/** @}
    542628 */
  • uspace/lib/softfloat/div.h

    r6069061 r58775d30  
    4242extern float128 div_float128(float128, float128);
    4343
     44#ifdef float32_t
     45extern float32_t __divsf3(float32_t, float32_t);
     46extern float32_t __aeabi_fdiv(float32_t, float32_t);
     47#endif
     48
     49#ifdef float64_t
     50extern float64_t __divdf3(float64_t, float64_t);
     51extern float64_t __aeabi_ddiv(float64_t, float64_t);
     52#endif
     53
     54#ifdef float128_t
     55extern float128_t __divtf3(float128_t, float128_t);
     56extern void _Qp_div(float128_t *, float128_t *, float128_t *);
     57#endif
     58
    4459#endif
    4560
  • uspace/lib/softfloat/mul.c

    r6069061 r58775d30  
    3434 */
    3535
    36 #include "sftypes.h"
    3736#include "mul.h"
    3837#include "comparison.h"
     
    6261                        return result;
    6362                }
     63               
    6464                if (is_float32_signan(b)) { /* TODO: fix SigNaN */
    6565                        result.parts.fraction = b.parts.fraction;
     
    6767                        return result;
    6868                }
     69               
    6970                /* set NaN as result */
    7071                result.bin = FLOAT32_NAN;
     
    7879                        return result;
    7980                }
     81               
    8082                result.parts.fraction = a.parts.fraction;
    8183                result.parts.exp = a.parts.exp;
     
    8991                        return result;
    9092                }
     93               
    9194                result.parts.fraction = b.parts.fraction;
    9295                result.parts.exp = b.parts.exp;
     
    106109        }
    107110       
    108         if (exp < 0) { 
     111        if (exp < 0) {
    109112                /* FIXME: underflow */
    110113                /* return signed zero */
     
    164167                /* denormalized number */
    165168                frac1 >>= 1; /* denormalize */
     169               
    166170                while ((frac1 > 0) && (exp < 0)) {
    167171                        frac1 >>= 1;
    168172                        ++exp;
    169173                }
     174               
    170175                if (frac1 == 0) {
    171176                        /* FIXME : underflow */
     
    175180                }
    176181        }
     182       
    177183        result.parts.exp = exp;
    178184        result.parts.fraction = frac1 & ((1 << FLOAT32_FRACTION_SIZE) - 1);
     
    380386}
    381387
     388#ifdef float32_t
     389
     390float32_t __mulsf3(float32_t a, float32_t b)
     391{
     392        float32_u ua;
     393        ua.val = a;
     394       
     395        float32_u ub;
     396        ub.val = b;
     397       
     398        float32_u res;
     399        res.data = mul_float32(ua.data, ub.data);
     400       
     401        return res.val;
     402}
     403
     404float32_t __aeabi_fmul(float32_t a, float32_t b)
     405{
     406        float32_u ua;
     407        ua.val = a;
     408       
     409        float32_u ub;
     410        ub.val = b;
     411       
     412        float32_u res;
     413        res.data = mul_float32(ua.data, ub.data);
     414       
     415        return res.val;
     416}
     417
     418#endif
     419
     420#ifdef float64_t
     421
     422float64_t __muldf3(float64_t a, float64_t b)
     423{
     424        float64_u ua;
     425        ua.val = a;
     426       
     427        float64_u ub;
     428        ub.val = b;
     429       
     430        float64_u res;
     431        res.data = mul_float64(ua.data, ub.data);
     432       
     433        return res.val;
     434}
     435
     436float64_t __aeabi_dmul(float64_t a, float64_t b)
     437{
     438        float64_u ua;
     439        ua.val = a;
     440       
     441        float64_u ub;
     442        ub.val = b;
     443       
     444        float64_u res;
     445        res.data = mul_float64(ua.data, ub.data);
     446       
     447        return res.val;
     448}
     449
     450#endif
     451
     452#ifdef float128_t
     453
     454float128_t __multf3(float128_t a, float128_t b)
     455{
     456        float128_u ua;
     457        ua.val = a;
     458       
     459        float128_u ub;
     460        ub.val = b;
     461       
     462        float128_u res;
     463        res.data = mul_float128(ua.data, ub.data);
     464       
     465        return res.val;
     466}
     467
     468void _Qp_mul(float128_t *c, float128_t *a, float128_t *b)
     469{
     470        *c = __multf3(*a, *b);
     471}
     472
     473#endif
     474
    382475/** @}
    383476 */
  • uspace/lib/softfloat/mul.h

    r6069061 r58775d30  
    3737#define __MUL_H__
    3838
     39#include <mathtypes.h>
     40
    3941extern float32 mul_float32(float32, float32);
    4042extern float64 mul_float64(float64, float64);
     
    4244extern float128 mul_float128(float128, float128);
    4345
     46#ifdef float32_t
     47extern float32_t __mulsf3(float32_t, float32_t);
     48extern float32_t __aeabi_fmul(float32_t, float32_t);
     49#endif
     50
     51#ifdef float64_t
     52extern float64_t __muldf3(float64_t, float64_t);
     53extern float64_t __aeabi_dmul(float64_t, float64_t);
     54#endif
     55
     56#ifdef float128_t
     57extern float128_t __multf3(float128_t, float128_t);
     58extern void _Qp_mul(float128_t *, float128_t *, float128_t *);
     59#endif
     60
    4461#endif
    4562
  • uspace/lib/softfloat/sub.c

    r6069061 r58775d30  
    3434 */
    3535
    36 #include "sftypes.h"
    3736#include "sub.h"
    3837#include "comparison.h"
    3938#include "common.h"
     39#include "add.h"
    4040
    4141/** Subtract two single-precision floats with the same sign.
     
    438438}
    439439
     440#ifdef float32_t
     441
     442float32_t __subsf3(float32_t a, float32_t b)
     443{
     444        float32_u ua;
     445        ua.val = a;
     446       
     447        float32_u ub;
     448        ub.val = b;
     449       
     450        float32_u res;
     451       
     452        if (ua.data.parts.sign != ub.data.parts.sign) {
     453                ub.data.parts.sign = !ub.data.parts.sign;
     454                res.data = add_float32(ua.data, ub.data);
     455        } else
     456                res.data = sub_float32(ua.data, ub.data);
     457       
     458        return res.val;
     459}
     460
     461float32_t __aeabi_fsub(float32_t a, float32_t b)
     462{
     463        float32_u ua;
     464        ua.val = a;
     465       
     466        float32_u ub;
     467        ub.val = b;
     468       
     469        float32_u res;
     470       
     471        if (ua.data.parts.sign != ub.data.parts.sign) {
     472                ub.data.parts.sign = !ub.data.parts.sign;
     473                res.data = add_float32(ua.data, ub.data);
     474        } else
     475                res.data = sub_float32(ua.data, ub.data);
     476       
     477        return res.val;
     478}
     479
     480#endif
     481
     482#ifdef float64_t
     483
     484float64_t __subdf3(float64_t a, float64_t b)
     485{
     486        float64_u ua;
     487        ua.val = a;
     488       
     489        float64_u ub;
     490        ub.val = b;
     491       
     492        float64_u res;
     493       
     494        if (ua.data.parts.sign != ub.data.parts.sign) {
     495                ub.data.parts.sign = !ub.data.parts.sign;
     496                res.data = add_float64(ua.data, ub.data);
     497        } else
     498                res.data = sub_float64(ua.data, ub.data);
     499       
     500        return res.val;
     501}
     502
     503float64_t __aeabi_dsub(float64_t a, float64_t b)
     504{
     505        float64_u ua;
     506        ua.val = a;
     507       
     508        float64_u ub;
     509        ub.val = b;
     510       
     511        float64_u res;
     512       
     513        if (ua.data.parts.sign != ub.data.parts.sign) {
     514                ub.data.parts.sign = !ub.data.parts.sign;
     515                res.data = add_float64(ua.data, ub.data);
     516        } else
     517                res.data = sub_float64(ua.data, ub.data);
     518       
     519        return res.val;
     520}
     521
     522#endif
     523
     524#ifdef float128_t
     525
     526float128_t __subtf3(float128_t a, float128_t b)
     527{
     528        float128_u ua;
     529        ua.val = a;
     530       
     531        float128_u ub;
     532        ub.val = b;
     533       
     534        float128_u res;
     535       
     536        if (ua.data.parts.sign != ub.data.parts.sign) {
     537                ub.data.parts.sign = !ub.data.parts.sign;
     538                res.data = add_float128(ua.data, ub.data);
     539        } else
     540                res.data = sub_float128(ua.data, ub.data);
     541       
     542        return res.val;
     543}
     544
     545void _Qp_sub(float128_t *c, float128_t *a, float128_t *b)
     546{
     547        *c = __subtf3(*a, *b);
     548}
     549
     550#endif
     551
    440552/** @}
    441553 */
  • uspace/lib/softfloat/sub.h

    r6069061 r58775d30  
    3737#define __SUB_H__
    3838
     39#include <mathtypes.h>
     40
    3941extern float32 sub_float32(float32, float32);
    4042extern float64 sub_float64(float64, float64);
     
    4244extern float128 sub_float128(float128, float128);
    4345
     46#ifdef float32_t
     47extern float32_t __subsf3(float32_t, float32_t);
     48extern float32_t __aeabi_fsub(float32_t, float32_t);
     49#endif
     50
     51#ifdef float64_t
     52extern float64_t __subdf3(float64_t, float64_t);
     53extern float64_t __aeabi_dsub(float64_t, float64_t);
     54#endif
     55
     56#ifdef float128_t
     57extern float128_t __subtf3(float128_t, float128_t);
     58extern void _Qp_sub(float128_t *, float128_t *, float128_t *);
     59#endif
     60
    4461#endif
    4562
Note: See TracChangeset for help on using the changeset viewer.