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

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

Re: [avr-gcc-list] mass stupidity with registers and longs


From: David Gay
Subject: Re: [avr-gcc-list] mass stupidity with registers and longs
Date: Mon, 17 Jan 2005 09:26:22 -0800
User-agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.7b) Gecko/20040316

Curtis Maloney wrote:

I give up. I've been trying to shift 4 chars into an unsigned long, but can't stop GCC 3.4.1 (what's shipped with the latest WinAVR) from sign extending values, let alone producing sane code.

I've tried -Os, -O2, -O3, with and without -fnew-ra... the asm varies, but is generaly crap.

now, if I have:
    extern char a[4];
    unsigned long ul;

    ul = ( (unsigned)a[0] << 8 ) | (unsigned)a[1];

why would it be sign extending a[0] and a[1] when they're cast to unsigneds? And then why doesn't the code optimiser see to just mov rX, a[1]; mov rX+1,a[0] ?

I tried casts on casts on casts... everything I could think of to get better code, and it just did not improve.

Am I missing something,

Yes. As others have not given the actual explanation of why what you did doesn't work, and why you actually did ask for those sign extensions:

- "char" is signed on most platforms (including avr-gcc)
- "unsigned" is a shorthand for "unsigned int", 16-bits with avr-gcc
- all expressions whose type is shorter than int are automatically converted to ints - therefore: a[0] is a char, so is converted to int. sign-extension happens as char is signed. All this occurs before the cast... - you then asked for a cast of '(int)a[0]' to (unsigned int). Not much actually happens here (the cast could have some effects depending on how the result is used, but not here).

Possible fixes (some already mentioned):
- declare a as "unsigned char a[4]". The conversion to int still happens, but it doesn't involve sign extension (it's a "zero extension"). The optimiser will typically get rid of the zero-extension. - cast a[0] to (unsigned char). The sign extension will also occur, but again, the optimiser will typically get rid of it (as the sign extended byte is discarded by the cast to unsigned char). - write 'a[0] & 0xff'. Effectively equivalent to the cast to 'unsigned char'.

The first solution is definitely the cleanest...

David Gay


reply via email to

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