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);
}

Attachment: signature.asc
Description: This is a digitally signed message part.

_______________________________________________
Tinycc-devel mailing list
[email protected]
https://lists.nongnu.org/mailman/listinfo/tinycc-devel

Reply via email to