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

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

[Fwd: Re: [avr-gcc-list] Re: Why is gcc promoting on an unsigned char?]


From: Frederik Rouleau
Subject: [Fwd: Re: [avr-gcc-list] Re: Why is gcc promoting on an unsigned char?]
Date: Tue, 23 Dec 2003 16:34:27 +0100
User-agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.4) Gecko/20030624 Netscape/7.1 (ax)

The pb may be the syntax of |=.

data |= (unsigned char) ((unsigned char) bit_is_set (DATAPIN, DATA) ? (unsigned char) i : (unsigned char) 0);

In my mind data |= x; is equivalent to data = data | x; so with the typecast data = data | (type)x; So the or result is promoted to int. You should try (type)data |= (type)x; or data = (type)data | (type)x;

So try :

(unsigned char)data |= (unsigned char) ((unsigned char) bit_is_set (DATAPIN, DATA) ? (unsigned char) i : (unsigned char) 0);



J.C. Wren wrote:

In the original code, there was some additional action that replaced the : 0 portion of the ternary operator. I had eliminated that in an effort to track down why it was getting promoted.

I rewrote the ?: slightly differently, so it's treated more like if/else. It produces the same code as the if() version. The second version (or more correctly, original version) of ?: is not optimizing correctly, based on my interpetation of the grammar. Considering that every thing is cast, I am unclear as to why it thinks it needs to promote to ints for the intermediate results.

What I can't determine is exactly what portion of the ?: clause is responsible for the promotion. While I'm familiar with compiler design in general, and have written several small grammars, GCCs complexity is a little hard to follow on short notice.

I know perfectly well some of the casts in the last example are not necessary, but I left them in for demonstation purposes.

        --jc

        
With if ()

  for (data = 0, i = 0; i <= 128; i <<= 1)
 78: 20 e0          ldi   r18, 0x00   ; 0
 7a: 82 2f          mov   r24, r18
  {
     loop_until_bit_is_clear (CLKPIN, CLK);     // Receive first databit
 7c: c8 99          sbic  0x19, 0  ; 25
 7e: fe cf          rjmp  .-4         ; 0x7c

     if (bit_is_set (DATAPIN, DATA))
 80: c9 99          sbic  0x19, 1  ; 25
        data |= i;
 82: 28 2b          or r18, r24
     else
        data |= 0;

     loop_until_bit_is_set (CLKPIN, CLK);
 84: c8 9b          sbis  0x19, 0  ; 25
 86: fe cf          rjmp  .-4         ; 0x84
 88: 88 0f          add   r24, r24
 8a: 81 38          cpi   r24, 0x81   ; 129
 8c: b8 f3          brcs  .-18        ; 0x7c
  }

While ?: operator, version 1

  for (data = 0, i = 0; i <= 128; i <<= 1)
 78: 20 e0          ldi   r18, 0x00   ; 0
 7a: 82 2f          mov   r24, r18
  {
     loop_until_bit_is_clear (CLKPIN, CLK);     // Receive first databit
 7c: c8 99          sbic  0x19, 0  ; 25
 7e: fe cf          rjmp  .-4         ; 0x7c

     bit_is_set (DATAPIN, DATA) ? (data |= i) : (data |= 0);
 80: c9 99          sbic  0x19, 1  ; 25
 82: 28 2b          or r18, r24

     loop_until_bit_is_set (CLKPIN, CLK);
 84: c8 9b          sbis  0x19, 0  ; 25
 86: fe cf          rjmp  .-4         ; 0x84
 88: 88 0f          add   r24, r24
 8a: 81 38          cpi   r24, 0x81   ; 129
 8c: b8 f3          brcs  .-18        ; 0x7c
  }

With ?: operator, version 2.

  for (data = 0, i = 0; i <= 128; i <<= 1)
 78: 20 e0          ldi   r18, 0x00   ; 0
 7a: 42 2f          mov   r20, r18
  {
     loop_until_bit_is_clear (CLKPIN, CLK);     // Receive first databit
 7c: c8 99          sbic  0x19, 0  ; 25
 7e: fe cf          rjmp  .-4         ; 0x7c
data |= (unsigned char) ((unsigned char) bit_is_set (DATAPIN, DATA) ? (unsigned char) i : (unsigned char) 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
     loop_until_bit_is_set (CLKPIN, CLK);
 96: c8 9b          sbis  0x19, 0  ; 25
 98: fe cf          rjmp  .-4         ; 0x96
 9a: 44 0f          add   r20, r20
 9c: 41 38          cpi   r20, 0x81   ; 129
 9e: 70 f3          brcs  .-36        ; 0x7c
  }



On Tuesday 23 December 2003 07:12 am, Neil Johnson wrote:
Hi,

I thnk Joerg has hit the nail on the head, but without explaining the
"why".  Here's my (brief) attempt.

Ok, here's your code:
     data |= (unsigned char) (bit_is_set (DATAPIN, DATA) ? i : 0);
As far as the compiler is concerned what you have expressed in the
language is something like:

        Place in var "data" the bitwise OR of the current value of
        var "data" and with the result of a conditional expression:
                The conditional expression evaluates the predicate
                        "bit_is_set (DATAPIN, DATA)"
                If this evaluates to non-zero, the result of the
                expression is the current value of var "i", otherwise
                it is the value zero.

This is one helluva thing to say, when in practice what you, perhaps,

meant to say is what Joerg wrote:
if (DATAPIN & DATA)
{
 data |= i;
}
Which means something like:

        If the result of the expression "DATAPIN & DATA" is non-zero then
                bitwise OR the var "data" with var "i".

This is far more concise, and will allow the optimizer to do its work
better.

Unless, of course, you would like to pay for a more expensive optimizer
which might have more smarts to try and unravel what you wrote :-)

Cheers, and a Happy Christmas and Fun New Year to All!!
Neil

--
Neil Johnson :: Computer Laboratory :: University of Cambridge ::
http://www.njohnson.co.uk          http://www.cl.cam.ac.uk/~nej22
----  IEE Cambridge Branch: http://www.iee-cambridge.org.uk  ----


_______________________________________________
avr-gcc-list mailing list
address@hidden
http://www.avr1.org/mailman/listinfo/avr-gcc-list

--
Frédérik ROULEAU <mailto:address@hidden>
Naotek S.A.R.L. <http://www.naotek.com>
Tél: +33 2 40 50 61 61
Fax: +33 2 40 50 61 62

reply via email to

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