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

[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



reply via email to

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