| #include <stdint.h> |
| #include <signal.h> |
| |
| #if BITS == 64 |
| typedef uint64_t unum; |
| typedef int64_t snum; |
| #else |
| typedef uint32_t unum; |
| typedef int32_t snum; |
| #endif |
| |
| #ifdef SIGNED |
| typedef snum xnum; |
| #else |
| typedef unum xnum; |
| #endif |
| |
| #ifdef __cris__ |
| static inline unum __attribute__ ((const))dstep(unum rs, unum rd) |
| { |
| asm("dstep %1,%0": "+r"(rd):"r"(rs)); |
| return rd; |
| } |
| |
| static inline unum __attribute__ ((const))lz(unum rs) |
| { |
| unum rd; |
| asm("lz %1,%0": "=r"(rd):"r"(rs)); |
| return rd; |
| } |
| |
| #else |
| /* For testing */ |
| static inline unum __attribute__ ((const))dstep(unum rs, unum rd) |
| { |
| rd <<= 1; |
| if (rd >= rs) |
| rd -= rs; |
| |
| return rd; |
| } |
| |
| static inline unum __attribute__ ((const))lz(unum rs) |
| { |
| unum rd = 0; |
| while (rs >= 0x7fffffff) { |
| rd++; |
| rs <<= 1; |
| } |
| return rd; |
| } |
| |
| #endif |
| |
| xnum NAME(unum num, unum den) |
| { |
| unum quot = 0, qbit = 1; |
| int minus = 0; |
| xnum v; |
| |
| if (den == 0) { |
| raise(SIGFPE); |
| return 0; /* If signal ignored... */ |
| } |
| |
| if (den == 1) |
| return (xnum) (REM ? 0 : num); |
| |
| #if SIGNED |
| if ((snum) (num ^ den) < 0) |
| minus = 1; |
| if ((snum) num < 0) |
| num = -num; |
| if ((snum) den < 0) |
| den = -den; |
| #endif |
| |
| den--; |
| |
| /* Left-justify denominator and count shift */ |
| while ((snum) den >= 0) { |
| den <<= 1; |
| qbit <<= 1; |
| } |
| |
| while (qbit) { |
| if (den <= num) { |
| num -= den; |
| quot += qbit; |
| } |
| den >>= 1; |
| qbit >>= 1; |
| } |
| |
| v = (xnum) (REM ? num : quot); |
| if (minus) |
| v = -v; |
| return v; |
| } |