[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Fwd: Re: [avr-gcc-list] Re: Why is gcc promoting on an unsigned cha
From: |
J.C. Wren |
Subject: |
Re: [Fwd: Re: [avr-gcc-list] Re: Why is gcc promoting on an unsigned char?] |
Date: |
Tue, 23 Dec 2003 11:07:42 -0500 |
User-agent: |
KMail/1.5.4 |
'data' was already declared as an unsigned char (should have included
that.
'i' is also UC). Deliberately casting 'data' to unsigned char didn't change
anything (and I would have been very surprised if it had, under the
circumstances).
--jc
On Tuesday 23 December 2003 10:34 am, Frederik Rouleau wrote:
> 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