Le jeudi 25 avril 2013 16:16:15, Thomas Preud'homme a écrit : > Le jeudi 25 avril 2013 16:05:24, Christian JULLIEN a écrit : > > Wouah! > > Do you mean you're implementing eabi_xxxx functions for ARM (such as div > > and mod ?) Total respect!! > > Yes but I'm not trying to make the fastest implementation possible. I do > try however to not suck too much. Eventually I'll try to do the one for > float but that's much more work.
Also since there is no support for arm asm, I'm implementing it in C. Hence it's really easy :) See attached file for my implementation. Note that the __aeabi_idiv(mod)? functions are not tested so far. Best regards, Thomas
//#include <stdint.h>
#include<limits.h>
/* TODO: add error in case of den == 0 (see §4.3.1 and §4.3.2) */
typedef struct {
int quot;
int rem;
} idiv_return;
typedef struct {
unsigned quot;
unsigned rem;
} uidiv_return;
static inline uidiv_return aeabi_uidivmod(unsigned num, unsigned den)
{
uidiv_return ret;
unsigned quot = 0;
/* Increase quotient while it is less than numerator */
while (num >= den) {
unsigned q = 1;
/* Find closest power of two */
while ((q << 1) * den <= num && q * den <= UINT_MAX / 2)
q <<= 1;
/* Compute difference between current quotient and numerator */
num -= q * den;
quot += q;
}
ret.quot = quot;
ret.rem = num;
return ret;
}
int __aeabi_idiv(int numerator, int denominator)
{
unsigned num, den;
uidiv_return ret;
num = numerator & INT_MAX;
den = denominator & INT_MAX;
ret = aeabi_uidivmod(num, den);
if ((numerator & INT_MIN) != (denominator & INT_MIN)) // signs differ
ret.quot *= -1;
return ret.quot;
}
unsigned __aeabi_uidiv(unsigned num, unsigned den)
{
return aeabi_uidivmod(num, den).quot;
}
idiv_return __aeabi_idivmod(int numerator, int denominator)
{
unsigned num, den;
uidiv_return uidiv_ret;
idiv_return ret;
num = numerator & INT_MAX;
den = denominator & INT_MAX;
uidiv_ret = aeabi_uidivmod(num, den);
if ((numerator & INT_MIN) != (denominator & INT_MIN)) // signs differ
ret.quot = uidiv_ret.quot * -1;
else
ret.quot = uidiv_ret.quot;
if (numerator & INT_MIN)
ret.rem = uidiv_ret.rem * -1;
else
ret.rem = uidiv_ret.rem;
return ret;
}
uidiv_return __aeabi_uidivmod(unsigned num, unsigned den)
{
return aeabi_uidivmod(num, den);
}
signature.asc
Description: This is a digitally signed message part.
_______________________________________________ Tinycc-devel mailing list [email protected] https://lists.nongnu.org/mailman/listinfo/tinycc-devel
