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

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

Re: [avr-gcc-list] Problem with signed 32bit ints? (now I am really conf


From: Mike Panetta
Subject: Re: [avr-gcc-list] Problem with signed 32bit ints? (now I am really confused..)
Date: 29 Jan 2003 12:23:25 -0500

Ok, I just got done writing some test code that tries to do what the
code thats not working does (multiply various things together, with
various different size arguments) and I cant get it to break in the same
way the real code does.  Whats even worse, is the test code never uses
the multiply instruction!!!  All it seems to do is a bunch of adds and
subtracts, where the real code calls something called __mulsi3.  So I am
completely stumped as to how I can reproduce this error in a small
simple function.  Does anyone know what exactly __mulsi3 is supposed to
do?  I gather it multiplies 2 numbers together, but what are its
argument types supposed to be?  The "broken" code calls __mulsi3 whether
or not the value I am assigning to is a 16 or a 32 bit value.  Is this
ok?  Could there be a bug in __mulsi3 that someone is not aware of,
because its a function that only gets used by the compiler in some
limited cases?  Why is the compiler using __mulsi3 for the real
function, but it does not use it in my test function?

Here is my test function:
void
TestINT32(void)
{

        int32_t a, b, c, x, y ,z;
        int16_t aa, bb;
        int8_t  aaa = 1;

        printf("Testing 32bit ints\n");
        delay_ms(10000);

        printf("Testing if n == n, (is a 32bit == a 16bit)\n");
        for (a = -4; a < 5; a++)
        {
                aa = a;
                if (a > aa)
                        printf("%ld > %d?!\n", a, aa);
                if (a < aa)
                        printf("%ld < %d?!\n", a, aa);
                if (a == aa)
                        printf("Test passed for a = %ld\n", a);
        }
        
        delay_ms(10000);
        delay_ms(10000);
        printf("Testing if n/1 == n/1 (32bit/8bit == 16bit/8bit)\n");
        for (a = -4; a < 5; a++)
        {
                aa = a;
                bb = aa/aaa;
                b  = a/aaa;
                if (b > bb)
                        printf("%ld > %d?!\n", b, bb);
                if (b < bb)
                        printf("%ld < %d?!\n", b, bb);
                if (b == bb)
                        printf("Test passed for a = %ld\n", b);
        }
        delay_ms(10000);
        delay_ms(10000);
        printf("Testing if n == 1 * n (32bit * 32bit == 8bit * 32bit)\n");
        for (a = -4; a < 5; a++)
        {
                aaa = 80;
                b   = 80;

                x = aaa * a;
                y = b   * a;

                if (x > y)
                        printf("%ld > %ld?!\n", x, y);
                if (x < y)
                        printf("%ld < %ld?!\n", x, y);
                if (x == y)
                        printf("Test passed for %ld = %d * %ld\n", x, aaa, a);
        }
        delay_ms(10000);
        delay_ms(10000);
        printf("Testing if n == 1 * n (32bit == 8bit * 32bit)\n");
        for (a = -4, aa = -4; a < 5; a++, aa++)
        {
                aaa = 1;
                b = aaa * a;
                if (aa > b)
                        printf("%d > %ld?!\n", aa, b);
                if (aa < b)
                        printf("%d < %ld?!\n", aa, b);
                if (aa == b)
                        printf("Test passed for a = %ld\n", b);
        }
        delay_ms(10000);
        delay_ms(10000);
        
}


On Tue, 2003-01-28 at 12:17, Mike Panetta wrote:
> 
> I think I am having a problem with signed 32bit ints on the avr.  Here
> is the function I am having problems with: 
> 
> int16_t 
> DoPid(MotorInfo * motor) 
> { 
> int32_t error; 
> int32_t drive; 
> int16_t Tp; //<--  I cant change these to int32_t 
> int16_t Ti; //              "  " 
> int16_t Td; //              "  " 
> 
> error = motor->setpoint - motor->position; 
> Tp = motor->Kp*error; 
> Td = motor->Kd*(error - motor->PrevErr); 
>         Ti = motor->Ki*motor->Ierror; 
> drive = (Tp+Td+Ti)/(int32_t)motor->Ko; 
> 
> motor->PrevErr = error; 
> 
> if (drive >= motor->maxDrive) 
> drive = motor->maxDrive; 
> else if (drive <= -(motor->maxDrive)) 
> drive = -(motor->maxDrive); 
> else 
> motor->Ierror += error;  
> motor->drive = drive; 
> return drive; 
> 
> } 
> 
> 
> If I change any of Tp, Ti, or Td to 32 bit ints the function fails to
> work when the value of any of the variables is negative.  The Kp, Ki,
> Kd, and Ko values in the struct MotorInfo are all signed 8 bit values. 
> Does anyone have any clue as to what I am doing wrong?  Or is it really
> a bug in the compiler?  Are there any known issues with mixing 32bit and
> 16bit or less values in a comparison or divide operation?  
> 
> Thanks, 
> Mike 
> 
> PS:  I am not on the list, so please CC me any response.
> 
> 
> avr-gcc-list at http://avr1.org


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



reply via email to

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