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: Rune Christensen
Subject: RE: [avr-gcc-list] Re: Why is gcc promoting on an unsigned char?
Date: Tue, 23 Dec 2003 07:37:56 +0100

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




reply via email to

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