blob: ebf81738ae7fb5f31bf33315700c7be31fa696fa [file] [log] [blame]
#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 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;
}