chiark / gitweb /
volume_id: provide libvolume_id.a file
[elogind.git] / klibc / klibc / arch / cris / divide.c
1 #include <stdint.h>
2 #include <signal.h>
3
4 #if BITS == 64
5 typedef uint64_t unum;
6 typedef int64_t  snum;
7 #else
8 typedef uint32_t unum;
9 typedef int32_t  snum;
10 #endif
11
12 #ifdef SIGNED
13 typedef snum xnum;
14 #else
15 typedef unum xnum;
16 #endif
17
18 #ifdef __cris__
19 static inline unum __attribute__((const)) dstep(unum rs, unum rd) {
20   asm("dstep %1,%0" : "+r" (rd) : "r" (rs));
21   return rd;
22 }
23
24 static inline unum __attribute__((const)) lz(unum rs) {
25   unum rd;
26   asm("lz %1,%0" : "=r" (rd) : "r" (rs));
27   return rd;
28 }
29
30 #else
31 /* For testing */
32 static inline unum __attribute__ ((const)) dstep(unum rs, unum rd) {
33   rd <<= 1;
34   if ( rd >= rs )
35     rd -= rs;
36
37   return rd;
38 }
39
40 static inline unum __attribute__((const)) lz(unum rs) {
41   unum rd = 0;
42   while ( rs >= 0x7fffffff ) {
43     rd++;
44     rs <<= 1;
45   }
46   return rd;
47 }
48
49 #endif
50
51 xnum NAME (unum num, unum den)
52 {
53   unum quot = 0, qbit = 1;
54   int minus = 0;
55   xnum v;
56   
57   if ( den == 0 ) {
58     raise(SIGFPE);
59     return 0;                   /* If signal ignored... */
60   }
61
62   if (den == 1) return (xnum)(REM ? 0 : num);
63
64 #if SIGNED
65   if ( (snum)(num^den) < 0 )
66     minus = 1;
67   if ( (snum)num < 0 ) num = -num;
68   if ( (snum)den < 0 ) den = -den;
69 #endif
70
71   den--;
72
73
74   /* Left-justify denominator and count shift */
75   while ( (snum)den >= 0 ) {
76     den <<= 1;
77     qbit <<= 1;
78   }
79
80   while ( qbit ) {
81     if ( den <= num ) {
82       num -= den;
83       quot += qbit;
84     }
85     den >>= 1;
86     qbit >>= 1;
87   }
88
89   v = (xnum)(REM ? num : quot);
90   if ( minus ) v = -v;
91   return v;
92 }