From: <cr...@ps...> - 2004-10-19 22:17:57
|
Hi I just debugged a wierd thing with the latest compiler (Downloaded most current source today, Oct 19,2004). I had a piece of code that looked like P1_6=~P1_6; where P1_6 is defined in a header file as sbit at 0x96 P1_6 ; when I looked at the resulting assembly code, I got a thing that looked like this ;main.c:334: P1_6 = ~P1_6; ; genCpl setb _P1_6 What I was looking for here was the complement (i.e. toggle the bit), not a set of the bit When I changed it to P1_6=!P1_6; The resulting assembly code looked like this ;main.c:334: P1_6 = !P1_6; ; genNot ; Peephole 167 removed redundant bit moves (c not set to _P1_6) cpl _P1_6 which was my desired result. Now for the question. Is this a compiler bug or my ignorance of what the ~ operator does? I was under the impression that "~" was the one's bit compliment, which for a single bit variable should be the same as "!". For those interested my compiler was /usr/local/bin/sdcc --version SDCC : mcs51/gbz80/z80/avr/ds390/pic16/pic14/TININative/xa51/ds400/hc08 2.4.5 #862 (Oct 19 2004) (UNIX) And the flags used looked like this /usr/local/bin/sdcc -c --model-large --iram-size 0x7f main.c Thanks -- Mike Crowe |
From: Joakim L. <joa...@se...> - 2004-10-20 14:52:54
|
Hi, I have a lot of code that I have been compiling with SDCC that contains constructs such as: P1_6 = ~(P1_6); It has always generated code that toggles the bit. This is the code now generated (an example): C$tweb.c$49$3$4 ==. ;/home/joakim/projects/webtermo/termo/tweb.c:49: P1_6 = ~(P1_6); // Toggle the LED ; genCpl setb _P1_6 The line "; genCpl" seems to indicate that the "complement value" is to be achieved and this has also been the case in SDCC for a long time. It is difficult for me to understand why this correct and logical behaviour has been changed. For all of us who already have software to maintain, it is a nightmare when a behaviour like this changes. Please, someone! Change the code generation so that a "cpl _P1_6" is generated instead of a "setb" Regards, Joakim Langlet |
From: Erik P. <epe...@iv...> - 2004-10-20 01:15:20
|
On Tue, 19 Oct 2004 cr...@ps... wrote: > Hi > I just debugged a wierd thing with the latest compiler (Downloaded > most current source today, Oct 19,2004). I had a piece of code that > looked like > P1_6=~P1_6; > where P1_6 is defined in a header file as > sbit at 0x96 P1_6 ; > > when I looked at the resulting assembly code, I got a thing that > looked like this > > ;main.c:334: P1_6 = ~P1_6; > ; genCpl > setb _P1_6 > > What I was looking for here was the complement (i.e. toggle the bit), > not a set of the bit > > When I changed it to > P1_6=!P1_6; > The resulting assembly code looked like this > ;main.c:334: P1_6 = !P1_6; > ; genNot > ; Peephole 167 removed redundant bit moves (c not set to _P1_6) > cpl _P1_6 > > which was my desired result. > > Now for the question. Is this a compiler bug or my ignorance of what > the ~ operator does? I was under the impression that "~" was the > one's bit compliment, which for a single bit variable should be the > same as "!". That would be true if bit & sbit were treated as single bit integers. In the current version of the sdcc, bit & sbit are considered boolean types, but subject to the C standard's integer promotion rules. In older versions of sdcc, they were also boolean types, but integer promotion was haphazardly applied, depending on the exact expression. Assume the variable b is declared as bit or sbit. If it currently has the value 0, then !b equals 1 and ~b equals 0xffff (since the C standard states that integer promotion be applied to the operand before performing a one's complement, and sdcc uses 16-bit ints). Alternatively, if it currently has the value 1, then !b equals 0 and ~b equals 0xfffe (again because of integer promotion). Since b is a boolean type, when assigning a value to b it only matters if the value is zero or non-zero. This is why b = ~b fails to work as you intend; it does not matter what b's original value is, ~b is always non-zero, so b will always be assigned a 1. One may argue that bit and sbit should not be treated as boolean types, but instead as a single bit unsignd int. In this case, b = ~b produces the same results as b = !b because all but the least significant bit will be discarded during the assignment. Assuming sdcc followed this type of implementation, there would likly be people complaining about this change in behavior too (since sdcc has traditionally treated bits/sbits as boolean types when assigned integer values). From a portability standpoint, b = !b will toggle a bit with the major commercial 8051 C compilers (Keil, Raisonance, Hi-Tech, and IAR). However, b = ~b will generate several different behaviors depending on the compiler and version. Take a look in the mailing list archive around mid-June 2004 for further discussion on this matter. Erik |
From: <cr...@ps...> - 2004-10-20 14:00:28
|
Erik Petrich wrote: > Take a look in the mailing list archive around mid-June 2004 for further > discussion on this matter. Looking back at the 6/18/04 discussion entitled "Re: [Sdcc-user] Bug in 15 June snapshot." helps lots. I guess I should have done more background research before posting. It was just that the behavior of ~ with respect to sbit had changed since sdcc 2.3.0 and I wanted to be sure to get out the message before I moved on to other things. Thanks again for all the help. Mike Crowe |
From: Jean-Paul <tch...@fr...> - 2004-10-20 06:44:33
|
Hello, Whatever the theory about bytes, bits etc. when I have to toggle a bit, I= =20 just write: P1_6^=3DP1_6. It has always worked. The exclusive OR is the logical operation you want, not invert. Regards Jean-Paul On Tue, 19 Oct 2004 17:17:44 -0500, <cr...@ps...> wrote: > > What I was looking for here was the complement (i.e. toggle the bit), =20 > not a set of the bit > > When I changed it to > P1_6=3D!P1_6; > The resulting assembly code looked like this > ;main.c:334: P1_6 =3D !P1_6; > ; genNot > ; Peephole 167 removed redundant bit moves (c not set to _P1_6= ) > cpl _P1_6 > > which was my desired result. > --=20 NEVER jump into a LOOP! |
From: Erik P. <epe...@iv...> - 2004-10-20 14:22:02
|
On Wed, 20 Oct 2004, Jean-Paul wrote: > Whatever the theory about bytes, bits etc. when I have to toggle a bit, I > just write: P1_6^=P1_6. It has always worked. > > The exclusive OR is the logical operation you want, not invert. Perhaps you meant P1_6=^1 ? Otherwise something exclusive-ored with itself would always be zero. Erik |
From: Erik P. <epe...@iv...> - 2004-10-20 14:24:25
|
On Wed, 20 Oct 2004, Erik Petrich wrote: > On Wed, 20 Oct 2004, Jean-Paul wrote: > > > Whatever the theory about bytes, bits etc. when I have to toggle a bit, I > > just write: P1_6^=P1_6. It has always worked. > > > > The exclusive OR is the logical operation you want, not invert. > > Perhaps you meant P1_6=^1 ? Otherwise something exclusive-ored with > itself would always be zero. I can't type either. How about P1_6^=1 ? |
From: Jean-Paul <tch...@fr...> - 2004-10-20 15:08:50
|
Yes, I meant P1_6^=3D1, which I do automatically. Here is what I was writing on Tue, 01 Jun 2004 13:58:41 +0200 answering to Peter Wein <pet...@gm...>: Hallo Peter, All your ISR routine has to do is: P5 ^=3D 4; the exclusive OR operation is sufficent to toggle the port pin. So, no need to define any variable inside the ISR. Jean-Paul On Wed, 20 Oct 2004 09:23:33 -0500 (CDT), Erik Petrich =20 <epe...@iv...> wrote: > > On Wed, 20 Oct 2004, Jean-Paul wrote: > >> Whatever the theory about bytes, bits etc. when I have to toggle a bit= , =20 >> I >> just write: P1_6^=3DP1_6. It has always worked. >> >> The exclusive OR is the logical operation you want, not invert. > > Perhaps you meant P1_6=3D^1 ? Otherwise something exclusive-ored with > itself would always be zero. > > Erik > --=20 NEVER jump into a LOOP! |