| #include <stdint.h> |
| #include <asm/gentrap.h> |
| #include <asm/pal.h> |
| |
| #if BITS == 64 |
| typedef uint64_t uint; |
| typedef int64_t sint; |
| #else |
| typedef uint32_t uint; |
| typedef int32_t sint; |
| #endif |
| |
| #ifdef SIGNED |
| typedef sint xint; |
| #else |
| typedef uint xint; |
| #endif |
| |
| xint NAME (uint num, uint den) |
| { |
| uint quot = 0, qbit = 1; |
| int minus = 0; |
| xint v; |
| |
| if ( den == 0 ) { |
| /* This is really $16, but $16 and $24 are exchanged by a script */ |
| register unsigned long cause asm("$24") = GEN_INTDIV; |
| asm volatile("call_pal %0" :: "i" (PAL_gentrap), "r" (cause)); |
| return 0; /* If trap returns... */ |
| } |
| |
| #if SIGNED |
| if ( (sint)(num^den) < 0 ) |
| minus = 1; |
| if ( (sint)num < 0 ) num = -num; |
| if ( (sint)den < 0 ) den = -den; |
| #endif |
| |
| /* Left-justify denominator and count shift */ |
| while ( (sint)den >= 0 ) { |
| den <<= 1; |
| qbit <<= 1; |
| } |
| |
| while ( qbit ) { |
| if ( den <= num ) { |
| num -= den; |
| quot += qbit; |
| } |
| den >>= 1; |
| qbit >>= 1; |
| } |
| |
| v = (xint)(REM ? num : quot); |
| if ( minus ) v = -v; |
| return v; |
| } |