Bug 21834 - Error when passing unsigned long long as function arguments
Summary: Error when passing unsigned long long as function arguments
Status: RESOLVED DUPLICATE of bug 27386
Alias: None
Product: gcc
Classification: Unclassified
Component: target (show other bugs)
Version: 3.4.3
: P2 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords: ABI, wrong-code
Depends on:
Blocks:
 
Reported: 2005-05-31 00:16 UTC by Richard Liu
Modified: 2007-05-30 20:29 UTC (History)
3 users (show)

See Also:
Host:
Target: AVR, Atmega128
Build:
Known to work:
Known to fail:
Last reconfirmed:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Richard Liu 2005-05-31 00:16:55 UTC
I have a function that takes two usigned-long-long variables and two unsigned-char variables as 
argument.  Here is the sample code:

typedef unsigned char byte_t;
typedef unsigned long long qword_t;
void foo(
    byte_t state,
    qword_t srcAddr,
    byte_t routeOptions,
    qword_t dstAddr
) {
    ...
}
void main(void) {
    ....
    foo(0x00,0x1234ll,0x01, 0x5678ll);
    ....
}

Compiled with avr-gcc 3.4.3, for Atmega 128:

avr-gcc -mmcu=atmega128 -g -Os -Wall -Wa,-adhlns=func1.o -std=gnu99 -funsigned-char 
-funsigned-bitfields -fpack-struct -fshort-enums -ffreestanding -c func1.c -o func1.o

When I tried to check the values of variable srcAddr and dstAddr within foo() using UART, they are not 
what they should be. srcAddr is something like 0xDE00000000001A6D,  and dstAddr is 
0x7800000000000056.

However, If I change the order of these arguments to :

void foo(
    qword_t srcAddr,
    qword_t dstAddr,
    byte_t state,
    byte_t routeOptions
) {
    ...
}

and the result would be correct.
Comment 1 Andrew Pinski 2005-05-31 02:50:25 UTC
Did you read: <http://gcc.gnu.org/bugs.html> because it says we don't want source with "...".
Comment 2 Richard Liu 2005-05-31 03:35:53 UTC
Fine, I'll list all codes if you insist:

#include <avr/io.h>

typedef unsigned char           byte_t;
typedef unsigned long long      qword_t;

void uart_init(void)
{
    // 115200 & 8N1
    UBRR1H = 0x00;
    UBRR1L = 0x08;
    UCSR1A |= (0x01<<U2X1);
    UCSR1C = 0x06;
    UCSR1B &= ~0x04;
    UCSR1B |= ((0x01<<RXEN1) | (0x01<<TXEN1));
}

void uart_putchar(byte_t octet)
{
    UDR1 = octet;
    while (!(UCSR1A & (0x01<<UDRE1)));
}

void uart_write(byte_t *octet, uint8_t len)
{
    while (len--) {
        UDR1 = *octet++;
        while (!(UCSR1A & (0x01<<UDRE1)));
    }
}

void foo( byte_t state, qword_t srcAddr, byte_t routeOptions, qword_t dstAddr )
{
    uart_putchar(state);
    uart_write((byte_t *)(&srcAddr),8);
    uart_putchar(routeOptions);
    uart_write((byte_t *)(&dstAddr),8);
}

void main(void) {
    uart_init();
    foo(0x00,0x1234ll,0x01, 0x5678ll);
    while(1);
}

and the output is:

D1,
34,12,D1,D1,D1,D1,D1,D1,
01,
AB,CD,00,CF,00,80,00,78

in hexdecimal format. Obviously it's incorrect.

If I change the code to:

#include <avr/io.h>

typedef unsigned char           byte_t;
typedef unsigned long long      qword_t;

void uart_init(void)
{
    // 115200 & 8N1
    UBRR1H = 0x00;
    UBRR1L = 0x08;
    UCSR1A |= (0x01<<U2X1);
    UCSR1C = 0x06;
    UCSR1B &= ~0x04;
    UCSR1B |= ((0x01<<RXEN1) | (0x01<<TXEN1));
}

void uart_putchar(byte_t octet)
{
    UDR1 = octet;
    while (!(UCSR1A & (0x01<<UDRE1)));
}

void uart_write(byte_t *octet, uint8_t len)
{
    while (len--) {
        UDR1 = *octet++;
        while (!(UCSR1A & (0x01<<UDRE1)));
    }
}

void foo( qword_t srcAddr, qword_t dstAddr, byte_t state, byte_t routeOptions )
{
    uart_putchar(state);
    uart_write((byte_t *)(&srcAddr),8);
    uart_putchar(routeOptions);
    uart_write((byte_t *)(&dstAddr),8);
}

void main(void) {
    uart_init();
    foo(0x1234ll,0x5678ll,0x00,0x01);
    while(1);
}

And the output will be:

00,
34,12,00,00,00,00,00,00,
01,
78,56,00,00,00,00,00,00

Compiling Procedure:

avr-gcc -mmcu=atmega128 -g -Os -Wall -Wa,-adhlns=main.lst -std=gnu99 -funsigned-char 
-funsigned-bitfields -fpack-struct -fshort-enums -ffreestanding -Wl,-Map=main.map -Wl,--cref  
main.c -o main.elf
avr-objcopy -O ihex -R .eeprom test.elf test.hex
avr-objcopy -j .eeprom --set-section-flags=.eeprom="alloc,load" --change-section-lma .eeprom=0 
-O ihex test.elf test.eep
avr-objdump -h -S test.elf > test.lss
avr-nm -n test.elf > test.sym

Programming with AVR Studio 4.11 build 401, JTAGICE mkII
Comment 3 Richard Liu 2005-05-31 03:38:40 UTC
Sorry, typo. Compile Procedure:

avr-gcc -mmcu=atmega128 -g -Os -Wall -Wa,-adhlns=test.lst -std=gnu99 -funsigned-char 
-funsigned-bitfields -fpack-struct -fshort-enums -ffreestanding -Wl,-Map=test.map -Wl,--cref  test.c 
-o test.elf
avr-objcopy -O ihex -R .eeprom test.elf test.hex
avr-objcopy -j .eeprom --set-section-flags=.eeprom="alloc,load" --change-section-lma .eeprom=0 
-O ihex test.elf test.eep
avr-objdump -h -S test.elf > test.lss
avr-nm -n test.elf > test.sym
Comment 4 Eric Weddington 2007-05-30 20:29:01 UTC
Marking this bug as duplicate of bug #27386 because that bug has reduced test case and more analysis.

*** This bug has been marked as a duplicate of 27386 ***