avr-gcc-list
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[avr-gcc-list] Multiply is broken on Mega128 (was: Problem with signed 3


From: Mike Panetta
Subject: [avr-gcc-list] Multiply is broken on Mega128 (was: Problem with signed 32bit ints?) a better test case
Date: 29 Jan 2003 16:25:18 -0500

Unless my knowledge about how binary multiplication works is wrong, and
my calculator is wrong, there is a problem with the way AVR-GCC does
multiplication of at least 8x16 and 16x16 data.  I have written a small
test case and will paste it at the end of this message.  If anyone wants
source I can fix that up and email it directly to you on request.

I have been looking in detail at the ASM output of AVR-GCC for these
multiply cases and it seems that it is truncating or at least improperly
creating the most significant 2 bytes of the 32bit result.  I am not
sure why its doing this.  If anyone could help me figure this out I
would be greatly appreciated.  If I have done something stupid, it would
be nice if you could explain to me what I have done wrong, as I am not
used to working with 8bit processors.  I am not sending any ASM output
with comments, because it may be different for people with different
processors.  If you want to see any ASM output, just reply and I can
paste it with comments as to what I think its doing, and where I think
its going wrong.  

Here is the test case:


struct test8x16Entry {
        int32_t x;
        int8_t  a;
        int16_t b;
};

struct test16x16Entry {
        int32_t x;
        int16_t a;
        int16_t b;
};

struct test8x16Entry t8x16[] = 
{
        {      0,   0,    0 },
        {      1,   1,    1 },
        {      4,   2,    2 },
        { -38100, 127, -300 },
        {  38100, 127,  300 },
        {4161409, 127, 32767},
};

struct test16x16Entry t16x16[] = 
{
        {      0,   0,    0 },
        {      1,   1,    1 },
        {      4,   2,    2 },
        { -38100, 127, -300 },
        {  38100, 127,  300 },
        {4161409, 127, 32767},
};

uint8_t T8x16SIZE = sizeof (t8x16)/sizeof (struct test8x16Entry);
uint8_t T16x16SIZE = sizeof (t16x16)/sizeof (struct test16x16Entry);
        

void
TestMultiply(void)
{
        int32_t x, y;
        int8_t  i;

        printf("Testing multiply\n");
        delay_ms(5000);
        printf("Testing x = a * b (32bit result, 8 and 16 bit
multiplicands)\n");
        for (i=0; i < T8x16SIZE; i++)
        {
                x = t8x16[i].a * t8x16[i].b;
                y = t8x16[i].x;

                if (x < y)
                        printf("%ld < %ld?! (%ld != %d * %d)\n", x, y, x, 
t8x16[i].a,
t8x16[i].b);
                if (x > y)
                        printf("%ld > %ld?! (%ld != %d * %d)\n", x, y, x, 
t8x16[i].a,
t8x16[i].b);
                if (x == y)
                        printf("Test passed for %ld = %d * %d\n", x, 
t8x16[i].a, t8x16[i].b);
        }

        delay_ms(5000);

        printf("Testing x = a * b (32bit result, 16 and 16 bit
multiplicands)\n");
        for (i=0; i < T16x16SIZE; i++)
        {
                x = t16x16[i].a * t16x16[i].b;
                y = t16x16[i].x;

                if (x < y)
                        printf("%ld < %ld?! (%ld != %d * %d)\n", x, y, x, 
t16x16[i].a,
t16x16[i].b);
                if (x > y)
                        printf("%ld > %ld?! (%ld != %d * %d)\n", x, y, x, 
t16x16[i].a,
t16x16[i].b);
                if (x == y)
                        printf("Test passed for %ld = %d * %d\n", x, 
t16x16[i].a,
t16x16[i].b);
        }


        delay_ms(10000);
        delay_ms(10000);
}

Thanks,
Mike

avr-gcc-list at http://avr1.org



reply via email to

[Prev in Thread] Current Thread [Next in Thread]