[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [avr-gcc-list] Re: Why is gcc promoting on an unsigned char?
From: |
Jörgen Birkler |
Subject: |
Re: [avr-gcc-list] Re: Why is gcc promoting on an unsigned char? |
Date: |
Tue, 23 Dec 2003 09:42:20 +0100 (CET) |
User-agent: |
SquirrelMail/1.4.0 |
Anser to your question is exactly what Rune says. It's the law...
If find that the avr-gcc compiler generally does some amazing
optimizations and register reuse when you inspect the generated code.
If you are really looking for those super optimaizations you can either:
1. Write assembler
2. Get another compiler (probably means you have to pay som $)
3. Help the compiler:
Instead of
data |= (unsigned char) (bit_is_set (DATAPIN, DATA) ? i : 0);
Try
if (DATAPIN & DATA)
{
data |= i;
}
Should do the same thing and the compiler seem to generate tighter code.
/Jörgen
> Well, we get marginally better results with this, but still 3 extra
> instructions. Putting in typecasts everywhere else in the statement as a
> test had no additional impact.
>
> --jc
>
> data |= (unsigned char) (bit_is_set (DATAPIN, DATA) ? i : 0);
> 80: 33 27 eor r19, r19
> 82: c9 9b sbis 0x19, 1 ; 25
> 84: 05 c0 rjmp .+10 ; 0x90
> 86: 84 2f mov r24, r20
> 88: 99 27 eor r25, r25
> 8a: 82 2b or r24, r18
> 8c: 93 2b or r25, r19
> 8e: 02 c0 rjmp .+4 ; 0x94
> 90: 93 2f mov r25, r19
> 92: 82 2f mov r24, r18
> 94: 28 2f mov r18, r24
>
>
> On Tuesday 23 December 2003 01:37 am, Rune Christensen wrote:
>> Hello
>>
>> I think that I have found an answer to you.
>>
>> Earlier Eric Weddington wrote:
>>
>> This is not a bug. The C Standard states that bitwise operators can
>> promote
>> a char to an int. GCC adheres to the Standard pretty closely, even
>> though
>> some things in the Standard are not amenable to embedded systems.
>> Remember
>> that GCC is used on a variety of computer platforms as well. This issue
>> is
>> also noted in the avr-libc FAQ (#20), which is in the avr-libc user
>> manual.
>> Did you look there?
>>
>> The workaround is to typecast the operation. For example if you are
>> clearing bits, you could do something like:
>>
>> (uint8_t)PORTB &= (uint8_t)~mask;
>>
>> Note that in the specific example of clearing bits, be sure to place the
>> typecast *before* the bitwise NOT operator, as that operator could
>> promote
>> to int.
>>
>> If you feel that liberally sprinkling typecasts would look ugly, you can
>> always create macros, such as:
>>
>> #define bit_clear_byte(var, mask) ((uint8_t)(var) &= (uint8_t)~(mask))
>>
>> bit_clear_byte(PORTB, 0x01);
>>
>> You can also define macros for 16-bit sizes:
>>
>> #define bit_clear_word(var, mask) ((uint16_t)(var) &=
>> (uint16_t)~(mask))
>>
>> And of course macros for setting bits, toggling bits, etc.
>>
>> -----Original Message-----
>> From: address@hidden
>> [mailto:address@hidden Behalf Of J.C. Wren
>> Sent: Tuesday, December 23, 2003 7:09 AM
>> To: address@hidden
>> Subject: [avr-gcc-list] Re: Why is gcc promoting on an unsigned char?
>>
>>
>> OK, part of that was my fault, I had "i << 1" instead of "1 << i". But
>> nonetheless, we still see some extra code at 0x94, 0x9c, 0xa0, and 0xa4.
>> The
>> compiler should be able to foresee the type of 'data', and not promote
>> the
>> intermediate results, right?
>>
>> --jc
>>
>> loop_until_bit_is_clear (CLKPIN, CLK); // Receive first
>> databit
>> 80: c8 99 sbic 0x19, 0 ; 25
>> 82: fe cf rjmp .-4 ; 0x80
>> data |= (bit_is_set (DATAPIN, DATA) ? (1 << i) : 0);
>> 84: 33 27 eor r19, r19
>> 86: c9 9b sbis 0x19, 1 ; 25
>> 88: 0b c0 rjmp .+22 ; 0xa0
>> 8a: 97 2f mov r25, r23
>> 8c: 86 2f mov r24, r22
>> 8e: 04 2e mov r0, r20
>> 90: 02 c0 rjmp .+4 ; 0x96
>> 92: 88 0f add r24, r24
>> 94: 99 1f adc r25, r25
>> 96: 0a 94 dec r0
>> 98: e2 f7 brpl .-8 ; 0x92
>> 9a: 82 2b or r24, r18
>> 9c: 93 2b or r25, r19
>> 9e: 02 c0 rjmp .+4 ; 0xa4
>> a0: 93 2f mov r25, r19
>> a2: 82 2f mov r24, r18
>> a4: 28 2f mov r18, r24
>> loop_until_bit_is_set (CLKPIN, CLK);
>> a6: c8 9b sbis 0x19, 0 ; 25
>> a8: fe cf rjmp .-4 ; 0xa6
>> aa: 4f 5f subi r20, 0xFF ; 255
>> ac: 48 30 cpi r20, 0x08 ; 8
>> ae: 40 f3 brcs .-48 ; 0x80
>> }
>>
>> On Tuesday 23 December 2003 00:58 am, J.C. Wren wrote:
>> > In this sample of code below, both i and data are defined as unsigned
>> > char. For some reason, GCC is effectively promoting i and data to an
>> int
>> > for the operations. The register tracking then fails to realize that
>> it
>> > already has r18 loaded at 0x98, and moves r24 back to r18, inspite of
>> > having just moved r18 to r24.
>> >
>> > By casting the (i << 1) to unsigned char, I can eliminate one
>>
>> instruction,
>>
>> > but no amount of casting can further reduce out the promotion to int
>> side
>> > effects.
>> >
>> > --jc
>> >
>> >
>> > data |= (bit_is_set (DATAPIN, DATA) ? (i << 1) : 0);
>> > 80: 33 27 eor r19, r19
>> > 82: c9 9b sbis 0x19, 1 ; 25
>> > 84: 07 c0 rjmp .+14 ; 0x94
>> > 86: 84 2f mov r24, r20
>> > 88: 99 27 eor r25, r25
>> > 8a: 88 0f add r24, r24
>> > 8c: 99 1f adc r25, r25
>> > 8e: 82 2b or r24, r18
>> > 90: 93 2b or r25, r19
>> > 92: 02 c0 rjmp .+4 ; 0x98
>> > 94: 93 2f mov r25, r19
>> > 96: 82 2f mov r24, r18
>> > 98: 28 2f mov r18, r24
>> >
>> > By casting the (i << 1) to unsigned char, I can eliminate one
>> instruction
>> >
>> > data |= (bit_is_set (DATAPIN, DATA) ? (unsigned char) (i << 1) :
>> > 0); 80: 33 27 eor r19, r19
>> > 82: c9 9b sbis 0x19, 1 ; 25
>> > 84: 06 c0 rjmp .+12 ; 0x92
>> > 86: 84 2f mov r24, r20
>> > 88: 88 0f add r24, r24
>> > 8a: 99 27 eor r25, r25
>> > 8c: 82 2b or r24, r18
>> > 8e: 93 2b or r25, r19
>> > 90: 02 c0 rjmp .+4 ; 0x96
>> > 92: 93 2f mov r25, r19
>> > 94: 82 2f mov r24, r18
>> > 96: 28 2f mov r18, r24
>>
>> _______________________________________________
>> avr-gcc-list mailing list
>> address@hidden
>> http://www.avr1.org/mailman/listinfo/avr-gcc-list
>
>
> _______________________________________________
> avr-gcc-list mailing list
> address@hidden
> http://www.avr1.org/mailman/listinfo/avr-gcc-list
>
----------------------
Jörgen Birkler
mailto:address@hidden
- [avr-gcc-list] Re: avr-gcc-list Digest, Vol 11, Issue 19, Ewout Boks, 2003/12/22
- [avr-gcc-list] Why is gcc promoting on an unsigned char?, J.C. Wren, 2003/12/23
- [avr-gcc-list] Re: Why is gcc promoting on an unsigned char?, J.C. Wren, 2003/12/23
- RE: [avr-gcc-list] Re: Why is gcc promoting on an unsigned char?, Rune Christensen, 2003/12/23
- Re: [avr-gcc-list] Re: Why is gcc promoting on an unsigned char?, J.C. Wren, 2003/12/23
- Re: [avr-gcc-list] Re: Why is gcc promoting on an unsigned char?,
Jörgen Birkler <=
- Re: [avr-gcc-list] Re: Why is gcc promoting on an unsigned char?, Neil Johnson, 2003/12/23
- Re: [avr-gcc-list] Re: Why is gcc promoting on an unsigned char?, J.C. Wren, 2003/12/23
- Re: [avr-gcc-list] Re: Why is gcc promoting on an unsigned char?, Neil Johnson, 2003/12/23
- Re: [avr-gcc-list] Re: Why is gcc promoting on an unsigned char?, J.C. Wren, 2003/12/23
- Re: [avr-gcc-list] Re: Why is gcc promoting on an unsigned char?, David Gay, 2003/12/23
- Re: [avr-gcc-list] Re: Why is gcc promoting on an unsigned char?, J.C. Wren, 2003/12/23