[Top][All Lists]
[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
- [avr-gcc-list] Multiply is broken on Mega128 (was: Problem with signed 32bit ints?) a better test case,
Mike Panetta <=