Subversion Repositories HelenOS

Rev

Rev 2071 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 2071 Rev 2505
Line 32... Line 32...
32
/** @file
32
/** @file
33
 */
33
 */
34
 
34
 
35
#include <genarch/softint/division.h>
35
#include <genarch/softint/division.h>
36
 
36
 
37
#define ABSVAL(x) ( (x) > 0 ? (x) : -(x))
37
#define ABSVAL(x) ((x) > 0 ? (x) : -(x))
38
#define SGN(x) ( (x) >= 0 ? 1 : 0 )
38
#define SGN(x) ((x) >= 0 ? 1 : 0)
39
                     
39
                     
40
static unsigned int divandmod32(unsigned int a, unsigned int b, unsigned int *remainder)
40
static unsigned int divandmod32(unsigned int a, unsigned int b,
-
 
41
    unsigned int *remainder)
41
{
42
{
42
    unsigned int result;
43
    unsigned int result;
43
    int steps = sizeof(unsigned int) * 8;
44
    int steps = sizeof(unsigned int) * 8;
44
   
45
   
45
    *remainder = 0;
46
    *remainder = 0;
Line 48... Line 49...
48
    if (b == 0) {
49
    if (b == 0) {
49
        /* FIXME: division by zero */
50
        /* FIXME: division by zero */
50
        return 0;
51
        return 0;
51
    }
52
    }
52
   
53
   
53
    if ( a < b) {
54
    if (a < b) {
54
        *remainder = a;
55
        *remainder = a;
55
        return 0;
56
        return 0;
56
    }
57
    }
57
 
58
 
58
    for ( ; steps > 0; steps--) {
59
    for (; steps > 0; steps--) {
59
        /* shift one bit to remainder */
60
        /* shift one bit to remainder */
60
        *remainder = ( (*remainder) << 1) | (( a >> 31) & 0x1);
61
        *remainder = ((*remainder) << 1) | (( a >> 31) & 0x1);
61
        result <<= 1;
62
        result <<= 1;
62
       
63
       
63
        if (*remainder >= b) {
64
        if (*remainder >= b) {
64
                *remainder -= b;
65
            *remainder -= b;
65
                result |= 0x1;
66
            result |= 0x1;
66
        }
67
        }
67
        a <<= 1;
68
        a <<= 1;
68
    }
69
    }
69
 
70
 
70
    return result;
71
    return result;
71
}
72
}
72
 
73
 
73
 
74
 
74
static unsigned long long divandmod64(unsigned long long a, unsigned long long b, unsigned long long *remainder)
75
static unsigned long long divandmod64(unsigned long long a,
-
 
76
    unsigned long long b, unsigned long long *remainder)
75
{
77
{
76
    unsigned long long result;
78
    unsigned long long result;
77
    int steps = sizeof(unsigned long long) * 8;
79
    int steps = sizeof(unsigned long long) * 8;
78
   
80
   
79
    *remainder = 0;
81
    *remainder = 0;
Line 82... Line 84...
82
    if (b == 0) {
84
    if (b == 0) {
83
        /* FIXME: division by zero */
85
        /* FIXME: division by zero */
84
        return 0;
86
        return 0;
85
    }
87
    }
86
   
88
   
87
    if ( a < b) {
89
    if (a < b) {
88
        *remainder = a;
90
        *remainder = a;
89
        return 0;
91
        return 0;
90
    }
92
    }
91
 
93
 
92
    for ( ; steps > 0; steps--) {
94
    for (; steps > 0; steps--) {
93
        /* shift one bit to remainder */
95
        /* shift one bit to remainder */
94
        *remainder = ( (*remainder) << 1) | ((a >> 63) & 0x1);
96
        *remainder = ((*remainder) << 1) | ((a >> 63) & 0x1);
95
        result <<= 1;
97
        result <<= 1;
96
       
98
       
97
        if (*remainder >= b) {
99
        if (*remainder >= b) {
98
                *remainder -= b;
100
            *remainder -= b;
99
                result |= 0x1;
101
            result |= 0x1;
100
        }
102
        }
101
        a <<= 1;
103
        a <<= 1;
102
    }
104
    }
103
 
105
 
104
    return result;
106
    return result;
Line 108... Line 110...
108
int __divsi3(int a, int b)
110
int __divsi3(int a, int b)
109
{
111
{
110
    unsigned int rem;
112
    unsigned int rem;
111
    int result;
113
    int result;
112
   
114
   
113
    result = (int)divandmod32(ABSVAL(a), ABSVAL(b), &rem);
115
    result = (int) divandmod32(ABSVAL(a), ABSVAL(b), &rem);
114
 
116
 
115
    if ( SGN(a) == SGN(b)) return result;
117
    if (SGN(a) == SGN(b))
-
 
118
        return result;
116
    return -result;
119
    return -result;
117
}
120
}
118
 
121
 
119
/* 64bit integer division */
122
/* 64bit integer division */
120
long long __divdi3(long long a, long long b)
123
long long __divdi3(long long a, long long b)
121
{
124
{
122
    unsigned long long rem;
125
    unsigned long long rem;
123
    long long result;
126
    long long result;
124
   
127
   
125
    result = (long long)divandmod64(ABSVAL(a), ABSVAL(b), &rem);
128
    result = (long long) divandmod64(ABSVAL(a), ABSVAL(b), &rem);
126
 
129
 
127
    if ( SGN(a) == SGN(b)) return result;
130
    if (SGN(a) == SGN(b))
-
 
131
        return result;
128
    return -result;
132
    return -result;
129
}
133
}
130
 
134
 
131
/* 32bit unsigned integer division */
135
/* 32bit unsigned integer division */
132
unsigned int __udivsi3(unsigned int a, unsigned int b)
136
unsigned int __udivsi3(unsigned int a, unsigned int b)
Line 148... Line 152...
148
    unsigned int rem;
152
    unsigned int rem;
149
    divandmod32(a, b, &rem);
153
    divandmod32(a, b, &rem);
150
   
154
   
151
    /* if divident is negative, remainder must be too */
155
    /* if divident is negative, remainder must be too */
152
    if (!(SGN(a))) {
156
    if (!(SGN(a))) {
153
        return -((int)rem);
157
        return -((int) rem);
154
    }
158
    }
155
   
159
   
156
    return (int)rem;
160
    return (int) rem;
157
}
161
}
158
 
162
 
159
/* 64bit remainder of the signed division */
163
/* 64bit remainder of the signed division */
160
long long __moddi3(long long a,long  long b)
164
long long __moddi3(long long a,long  long b)
161
{
165
{
162
    unsigned long long rem;
166
    unsigned long long rem;
163
    divandmod64(a, b, &rem);
167
    divandmod64(a, b, &rem);
164
   
168
   
165
    /* if divident is negative, remainder must be too */
169
    /* if divident is negative, remainder must be too */
166
    if (!(SGN(a))) {
170
    if (!(SGN(a))) {
167
        return -((long long)rem);
171
        return -((long long) rem);
168
    }
172
    }
169
   
173
   
170
    return (long long)rem;
174
    return (long long) rem;
171
}
175
}
172
 
176
 
173
/* 32bit remainder of the unsigned division */
177
/* 32bit remainder of the unsigned division */
174
unsigned int __umodsi3(unsigned int a, unsigned int b)
178
unsigned int __umodsi3(unsigned int a, unsigned int b)
175
{
179
{
Line 184... Line 188...
184
    unsigned long long rem;
188
    unsigned long long rem;
185
    divandmod64(a, b, &rem);
189
    divandmod64(a, b, &rem);
186
    return rem;
190
    return rem;
187
}
191
}
188
 
192
 
189
unsigned long long __udivmoddi3(unsigned long long a, unsigned long long b, unsigned long long *c)
193
unsigned long long __udivmoddi3(unsigned long long a, unsigned long long b,
-
 
194
    unsigned long long *c)
190
{
195
{
191
    return divandmod64(a, b, c);
196
    return divandmod64(a, b, c);
192
}
197
}
193
 
198
 
194
/** @}
199
/** @}