Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/lib/softint/generic/multiplication.c

    rd27ed12 r9539be6  
    2929/** @addtogroup softint
    3030 * @{
    31  */ 
     31 */
    3232/**
    3333 * @file
     
    3636
    3737#include <multiplication.h>
    38 #include <stdint.h> 
     38#include <stdint.h>
    3939
    40 /** Set 1 to return MAX_INT64 or MIN_INT64 on overflow */
     40/** Set 1 to return INT64_MAX or INT64_MIN on overflow */
    4141#ifndef SOFTINT_CHECK_OF
    42 # define SOFTINT_CHECK_OF 0
     42        #define SOFTINT_CHECK_OF 0
    4343#endif
    4444
    45 /**
    46  * Multiply two integers and return long long as result.
     45/** Multiply two integers and return long long as result.
     46 *
    4747 * This function is overflow safe.
    48  * @param a
    49  * @param b
    50  * @result
     48 *
    5149 */
    5250static unsigned long long mul(unsigned int a, unsigned int b) {
    53         unsigned int a1, a2, b1, b2;
    54         unsigned long long t1, t2, t3; 
    55 
    56         a1 = a >> 16;
    57         a2 = a & MAX_UINT16;
    58         b1 = b >> 16;
    59         b2 = b & MAX_UINT16;
    60 
    61         t1 = a1 * b1;
    62         t2 = a1*b2;
    63         t2 += a2*b1;
    64         t3 = a2*b2;
    65 
    66         t3 = (((t1 << 16) + t2) << 16) + t3;
    67 
     51        unsigned int a1 = a >> 16;
     52        unsigned int a2 = a & UINT16_MAX;
     53        unsigned int b1 = b >> 16;
     54        unsigned int b2 = b & UINT16_MAX;
     55       
     56        unsigned long long t1 = a1 * b1;
     57        unsigned long long t2 = a1 * b2;
     58        t2 += a2 * b1;
     59        unsigned long long t3 = a2 * b2;
     60       
     61        t3 = (((t1 << 16) + t2) << 16) + t3;
     62       
    6863        return t3;
    6964}
     
    7469long long __muldi3 (long long a, long long b)
    7570{
    76         long long result;
    77         unsigned long long t1,t2;
    78         unsigned long long a1, a2, b1, b2;
    7971        char neg = 0;
    80 
     72       
    8173        if (a < 0) {
    8274                neg = !neg;
    8375                a = -a;
    8476        }
    85 
     77       
    8678        if (b < 0) {
    8779                neg = !neg;
    8880                b = -b;
    8981        }
    90 
    91         a1 = a >> 32;
    92         b1 = b >> 32;
    93 
    94         a2 = a & (MAX_UINT32);
    95         b2 = b & (MAX_UINT32);
    96 
     82       
     83        unsigned long long a1 = a >> 32;
     84        unsigned long long b1 = b >> 32;
     85       
     86        unsigned long long a2 = a & (UINT32_MAX);
     87        unsigned long long b2 = b & (UINT32_MAX);
     88       
    9789        if (SOFTINT_CHECK_OF && (a1 != 0) && (b1 != 0)) {
    98                 // error, overflow
    99                 return (neg?MIN_INT64:MAX_INT64);
     90                /* Error (overflow) */
     91                return (neg ? INT64_MIN : INT64_MAX);
    10092        }
    101 
    102         // (if OF checked) a1 or b1 is zero => result fits in 64 bits, no need to another overflow check
    103         t1 = mul(a1,b2) + mul(b1,a2);   
    104 
    105         if (SOFTINT_CHECK_OF && t1 > MAX_UINT32) {
    106                 // error, overflow
    107                 return (neg?MIN_INT64:MAX_INT64);
     93       
     94        /* (if OF checked) a1 or b1 is zero => result fits in 64 bits,
     95         * no need to another overflow check
     96         */
     97        unsigned long long t1 = mul(a1, b2) + mul(b1, a2);
     98       
     99        if ((SOFTINT_CHECK_OF) && (t1 > UINT32_MAX)) {
     100                /* Error (overflow) */
     101                return (neg ? INT64_MIN : INT64_MAX);
    108102        }
    109 
     103       
    110104        t1 = t1 << 32;
    111         t2 = mul(a2,b2);
     105        unsigned long long t2 = mul(a2, b2);
    112106        t2 += t1;
    113 
     107       
    114108        /* t2 & (1ull << 63) - if this bit is set in unsigned long long,
    115109         * result does not fit in signed one */
    116110        if (SOFTINT_CHECK_OF && ((t2 < t1) || (t2 & (1ull << 63)))) {
    117111                // error, overflow
    118                 return (neg?MIN_INT64:MAX_INT64);
     112                return (neg ? INT64_MIN : INT64_MAX);
    119113        }
    120 
    121         result = t2;
    122 
    123         if (neg) {
     114       
     115        long long result = t2;
     116        if (neg)
    124117                result = -result;
    125         }
    126 
     118       
    127119        return result;
    128 }       
     120}
    129121
    130122/** @}
Note: See TracChangeset for help on using the changeset viewer.