From: Royce & S. P. <be...@et...> - 2004-06-18 04:05:40
|
Hi Maarten, ----- Original Message ----- > > And finally, your bug was no bug in SDCC, but in your own C code. I would be more helpful if you could point out the mistake in my code. I looked through it again & it still evaded me. Thanks, --Royce. |
From: Royce & S. P. <be...@et...> - 2004-06-18 04:39:50
|
Hi Maarten ----- Original Message ----- From: "Royce & Sharal Pereira" <be...@et...> To: "SDCC" <sdc...@li...> Sent: Friday, June 18, 2004 9:33 AM Subject: Fw: [Sdcc-user] Bug in 15 June snapshot. > Hi Maarten, Thanks for your reply! > ----- Original Message ----- > > > > And finally, your bug was no bug in SDCC, but in your own C code. > > I would be more helpful if you could point out the mistake in my code. I looked through it again & > it still evaded me. ---*Sorry*, I take that back! I see you have posted your comments on the bug report. My point is: Are not the two functions (logically) the same? The bit variable is not promoted to int in the 2nd example, so why so in the 1st? Shouldnt ~P1_0 behave same in both contexts? I always understood a bit to be unsigned. >If you intend to invert the boolean value use ! instead (snip from bug report comment). ---My intention was not really to check the boolean value, which generally is the result of a logical operation. All I needed was to invert a bit & save it in another bit --Thanks for your help again, --Royce. |
From: Bernhard H. <ber...@be...> - 2004-06-18 09:03:32
|
> My point is: Are not the two functions (logically) the same? No. > The bit variable is not promoted to int > in the 2nd example, so why so in the 1st? The result of ~0 is 0xff. The result of ~1 is 0xfe. If you assign 0xff or 0xfe to a bit, the bit will be set. To get the correct result the promotion is necessary, sdcc is correct. The result of !0 is 1. The result of !1 is 0. Obviously the result of the not-operation on a bit still fits into a bit. Therefore there's no promotion necessary. > Shouldnt ~P1_0 behave same in both contexts? No. > I always understood a bit to be unsigned. Yes and no. From the doc: "In accordance with ISO/IEC 9899 bits and bitfields without an explicit signed modifier are implemented as unsigned." The signedness of a bitfield without an explicit modifier is implementation-defined. I've decided that a "plain" bitfield in sdcc is unsigned, because this is what most people expect and (more important) AFAIK signed bitfields don't work at all in sdcc. Furthermore there's no type "bit" in ISO/IEC 9899, in sdcc it behaves like a bitfield. See: http://sdcc.sourceforge.net/doc/sdccman.html/node123.html Bernhard |
From: Chris E. <sdc...@ma...> - 2004-06-18 09:20:20
|
On Fri, Jun 18, 2004 at 11:03:01AM +0200, Bernhard Held wrote: > > The bit variable is not promoted to int > > in the 2nd example, so why so in the 1st? > The result of ~0 is 0xff. > The result of ~1 is 0xfe. > If you assign 0xff or 0xfe to a bit, the bit will be set. To get the correct > result the promotion is necessary, sdcc is correct. IMHO, I would expect a bit to behave like a 1-bit integer, so assigning to it would truncate the high bits. In this case assigning any even number (eg 0xfe == 254) would give 0, and any odd number (eg 0xff == 255) would give 1. The behaviour you're describing is more like a boolean, where anything non-zero is equivalent to 1. If it's supposed to behave like bitfields, how would you expect a 2-bit bitfield to behave? Chris |
From: Bernhard H. <ber...@be...> - 2004-06-18 09:50:58
|
> IMHO, I would expect a bit to behave like a 1-bit integer, so assigning > to it would truncate the high bits. In this case assigning any even > number (eg 0xfe == 254) would give 0, and any odd number (eg 0xff == > 255) would give 1. > > The behaviour you're describing is more like a boolean, where anything > non-zero is equivalent to 1. > > If it's supposed to behave like bitfields, how would you expect a 2-bit > bitfield to behave? Indeed bits and 1-bit bitfields behave different, see: https://sourceforge.net/tracker/?func=detail&atid=100599&aid=510682&group_id=599 char c; struct { int b1 : 1; int b2 : 2; } bitfield; bitfield.b1 = c; bitfield.b2 = c; is evaluated as "bitfield.b1 = c & 1;" and "bitfield.b2 = c & 3;", whereas char c; bit b; b = c; is evaluated as "b = c ? 1 : 0;" Bernhard |
From: Erik P. <epe...@iv...> - 2004-06-18 18:55:40
|
On Fri, 18 Jun 2004, Bernhard Held wrote: > > My point is: Are not the two functions (logically) the same? > No. I agree. > > The bit variable is not promoted to int > > in the 2nd example, so why so in the 1st? This inconsistency is worth a further look. > The result of ~0 is 0xff. > The result of ~1 is 0xfe. > If you assign 0xff or 0xfe to a bit, the bit will be set. To get the correct > result the promotion is necessary, sdcc is correct. > The result of !0 is 1. > The result of !1 is 0. > Obviously the result of the not-operation on a bit still fits into a bit. > Therefore there's no promotion necessary. > > > Shouldnt ~P1_0 behave same in both contexts? > No. I disagree. ISO/IEC 9899 states that the "result of the ~ operator is the bitwise complement of its (promoted) operand". So P1_0 should be promoted before applying the complement operator regardless of how the expression is used (or at least resolve to the same result as if it were promoted). > > I always understood a bit to be unsigned. > Yes and no. From the doc: > "In accordance with ISO/IEC 9899 bits and bitfields without an explicit > signed modifier are implemented as unsigned." > The signedness of a bitfield without an explicit modifier is > implementation-defined. I've decided that a "plain" bitfield in sdcc is > unsigned, because this is what most people expect and (more important) AFAIK > signed bitfields don't work at all in sdcc. Furthermore there's no type > "bit" in ISO/IEC 9899, in sdcc it behaves like a bitfield. In SDCC, "bit" does not behave like a bitfield. For SDCC, type "bit" acts likes a boolean (ISO/IEC 9899 type "_Bool"). The result of assigning any non-zero value is 1. Bitfields act like a signed or unsigned int, but possibly have a smaller width. Assignment of a value outside of the representable range results in the truncation of the bits that don't fit. At the moment, SDCC does not support signed bitfields. Since "bit" is not defined by the C standard, its implementation varies between various 8051 C compilers. I experimented with a number of other compilers today (like SDCC, their documentation is not as explicit as it should be about this language extension). Keil's C51 and Raisonance's RC-51 treats "bit" as a boolean type. Hi-Tech's 8051-C treats "bit" as an unsigned int with a width of 1. It seems that none of these perform integer promotion on bit operands (except during assignment). Erik |
From: Bernhard H. <ber...@be...> - 2004-06-20 09:26:53
|
> > > Shouldnt ~P1_0 behave same in both contexts? > > > > No. > > I disagree. ISO/IEC 9899 states that the "result of the ~ operator is the > bitwise complement of its (promoted) operand". So P1_0 should be promoted > before applying the complement operator regardless of how the expression > is used (or at least resolve to the same result as if it were promoted). My focus was on the difference between ~ and !, and they are not the same; sorry, I wasn't specific enough and you're of course right. ~ should behave the same in func1() and func2() from the bug report. Bernhard |
From: Royce & S. P. <be...@et...> - 2004-06-18 15:26:30
|
Hi all, ----- Original Message ----- > > Shouldnt ~P1_0 behave same in both contexts? > No. > > "In accordance with ISO/IEC 9899 bits and bitfields without an explicit > signed modifier are implemented as unsigned." //--------------------------------------------------------------------- I think things are getting out of hand here :)) This is really not a debate on C conventions, but an SDCC query. Let me simplify my query: why does SDCC allow us to write: P1_0= ~P2_1; //and get away with it, but not: P1_0= (some_comparison) ? 0 : ~P2_1; //?? Why does SDCC consider the ~P_2_1 of the 1st case to be different from the 2nd ? If it correctly inverts the bit & saves it in the 1st case, why does it also not do so in the 2nd case when 'some_comparison' is false? I have been using SDCC since V2.2 where even the 1st case used to cast the bit as int & back to bit etc..etc.., in comparison to optimisazations of V2.3+ ! --Thanks, --Royce. |
From: Bernhard H. <ber...@be...> - 2004-06-18 15:35:38
|
> P1_0= ~P2_1; //and get away with it, but not: > > P1_0= (some_comparison) ? 0 : ~P2_1; //?? > > Why does SDCC consider the ~P_2_1 of the 1st case to be different from the 2nd ? > If it correctly inverts the bit & saves it in the 1st case, why does it also not do so in the 2nd > case when 'some_comparison' is false? Simple answer: the first case exhibits a bug in sdcc. P1_0 should always be set to 1. I've already invested a lot of time in this promotion thing to make sdcc compliant. But I've to admit that I disregarded to look after all this bit and bitfield stuff. There's still some way to go ... Bernhard |
From: Royce & S. P. <be...@et...> - 2004-06-19 07:15:10
|
Hi, ----- Original Message ----- > > > My point is: Are not the two functions (logically) the same? > > No. > > I agree. --I disagree here. Coz if the said variables were chars instead of bits, the end result (I dont mean the asm code) is the same in both cases. So there is no excuse to not get the same result just because the variables happen to be bits > > > The bit variable is not promoted to int > > > in the 2nd example, so why so in the 1st? > > This inconsistency is worth a further look. //--------------------------------------------------------------- I think '!' is a comparison and ~ is an actual operation on the variable?. In dummy-ish, bitvar2= !bitvar1 should mean"if bitvar1 is zero bitvar2=1, else bitvar2=0." and bitvar2= ~bitvar1 should mean "save the (bitwise)complement of bitvar1 in bitvar2". I really think bits(I dont mean bitfields, but the 128 bits starting from 0x20 in iram of 8051 & whose data type is 'bit') should not treated as boolean values. Esp. since the assember expects a specific 'ds 1' statement for each bit. Since 'bit' (as Erik pointed out) is not defined by the C standard, it is up to us to interpret it. The whole point of having a new "bit(and 'sbit')' data type is to create more efficient code by taking advantage of the 8051's bit manipulation ability. So 'bit' data type *must* be treated as a special case, and include a maximum level of optimisation with little regard to conformity.. If we dont do so, we betray the whole purpose of having a separate 'bit' data type. so, from a common sense point of view, P1_0= ~P2_1 ; generating mov c,_P2_1 cpl c mov _P1_0,c is correct, as also: P2_1= ~P2_1 generating cpl _P2_1; both of which, SDCC does now. How depressing, if the above was implemented by casting P2_1 as int ...operation... then back from int to bit, then out to P1_0, all in the name of 'conforming '. So much ado for a simple task! ;) Now, P1_0= !P2_1 also generates: mov c,_P2_1 cpl c mov _P1_0,c which is actually an optimised version of what should be: jb _P2_1 $100 setb _P1_0 $100: clr _P1_0 Remember we are compiling for a chip with limited resources, and optimisation is what its all about . Anyways the question of conforming does not arise here at all, as 'bit'(i.e data type 'bit') is not defined by any C standard! I suggest we create a standard for the 'bit' , so that ~bitvar and !bitvar always behave the same in all contexts, so we dont need wonder : " Now..should I use !P2_1 here... or maybe ~P2_1...?". Thanks! --Royce. |
From: Erik P. <epe...@iv...> - 2004-06-19 09:25:02
|
On Sat, 19 Jun 2004, Royce & Sharal Pereira wrote: > Date: Sat, 19 Jun 2004 12:44:57 +0530 > From: Royce & Sharal Pereira <be...@et...> > Reply-To: sdc...@li... > Cc: SDCC <sdc...@li...> > Subject: Fw: [Sdcc-user] Bug in 15 June snapshot. > > Hi, > ----- Original Message ----- > > > > My point is: Are not the two functions (logically) the same? > > > No. > > > > I agree. > > --I disagree here. > Coz if the said variables were chars instead of bits, the end result > (I dont mean the asm code) is the same in both cases. So there is no > excuse to not get the same result just because the variables happen to > be bits I may have misunderstood the reference to the "two functions". If it's the code fragment in your bug report: #include "8051.h" unsigned char value void func1() { P1_2 = (value == 2) ? 0 : ~P1_0; } void func2() { if (value == 2) P1_2 = 0; else P1_2 = ~P1_0; } then I agree that func1() should functionally equivalent to func2() with respect to the value stored in P1_2. > Since 'bit' (as Erik pointed out) is not defined by the C standard, it > is up to us to interpret it. The whole point of having a new "bit(and > 'sbit')' data type is to create more efficient code by taking > advantage of the 8051's bit manipulation ability. > So 'bit' data type *must* be treated as a special case, and include a > maximum level of optimisation with little regard to conformity.. > If we dont do so, we betray the whole purpose of having a separate > 'bit' data type. But we could have optimal code and still comply with the spirit of the standard. I don't see what benefit non-conformity would bring. My previous references to integer promotion do not necessarily imply that extra code will be generated for the promotion (it can be optimized out if the result is the same as if it occured), so it is not inherently inefficient. > Remember we are compiling for a chip with limited resources, and > optimisation is what its all about. > > Anyways the question of conforming does not arise here at all, as > 'bit'(i.e data type 'bit') is not defined by any C standard! > > I suggest we create a standard for the 'bit' , so that ~bitvar and > !bitvar always behave the same in all contexts, so we dont need > wonder: " Now..should I use !P2_1 here... or maybe ~P2_1...?". SDCC considers "bit" to be a boolean type; with this information, you should never have to wonder again. However, the adventurous could also consider -P2_1, thus completing the trio of negation operators (this would actually work as you intend, provided that the result is assigned to a bit variable). Erik |
From: Bernhard H. <ber...@be...> - 2004-06-20 09:26:53
|
Let's summarize some bit-operations together with the correct and optimal code: bit r, a, b; r = ~a; r = 1; setb r ; this will become a FAQ :-) r = !a; mov c,a cpl c mov r,c r = -a; r = a << b; /* a nice one: b has no influence on the result */ r = a; mov c,a mov r,c r = a + b; r = a | b; r = a || b; mov c,a orl c,b mov r,c r = a * b; r = a / b; r = a & b; r = a && b; mov c,a anl c,b mov r,c r = a >> b; mov c,a jnb b,.exit clr c .exit: mov r,c Bernhard |
From: Maarten B. <sou...@ds...> - 2004-06-20 10:36:45
|
<?xml version="1.0" ?><html> <head> <title></title> </head> <body> <div align="left"><font face="Arial" color="#7f0000"><span style="font-size:10pt">> Let's summarize some bit-operations together with the correct and</span></font></div> <div align="left"><font face="Arial" color="#7f0000"><span style="font-size:10pt">> optimal code:</span></font></div> <div align="left"><font face="Arial" color="#7f0000"><span style="font-size:10pt">> </span></font></div> <div align="left"><font face="Arial" color="#7f0000"><span style="font-size:10pt">> bit r, a, b;</span></font></div> <div align="left"><font face="Arial" color="#7f0000"><span style="font-size:10pt">> </span></font></div> <div align="left"><font face="Arial" color="#7f0000"><span style="font-size:10pt">> r = ~a;</span></font></div> <div align="left"><font face="Arial" color="#7f0000"><span style="font-size:10pt">> r = 1;</span></font></div> <div align="left"><font face="Arial" color="#7f0000"><span style="font-size:10pt">>  setb r           ; this will become a FAQ :-)</span></font></div> <div align="left"><font face="Arial" color="#7f0000"><span style="font-size:10pt">> </span></font></div> <div align="left"><font face="Arial" color="#7f0000"><span style="font-size:10pt">> r = !a;</span></font></div> <div align="left"><font face="Arial" color="#7f0000"><span style="font-size:10pt">>  mov c,a</span></font></div> <div align="left"><font face="Arial" color="#7f0000"><span style="font-size:10pt">>  cpl   c</span></font></div> <div align="left"><font face="Arial" color="#7f0000"><span style="font-size:10pt">>  mov  r,c</span></font></div> <div align="left"><font face="Arial" color="#7f0000"><span style="font-size:10pt">> </span></font></div> <div align="left"><font face="Arial" color="#7f0000"><span style="font-size:10pt">> r = -a;</span></font></div> <div align="left"><font face="Arial" color="#7f0000"><span style="font-size:10pt">> r = a << b;                 /* a nice one: b has no influence on the result */</span></font></div> <div align="left"><font face="Arial" color="#7f0000"><span style="font-size:10pt">> r = a;</span></font></div> <div align="left"><font face="Arial" color="#7f0000"><span style="font-size:10pt">>  mov  c,a</span></font></div> <div align="left"><font face="Arial" color="#7f0000"><span style="font-size:10pt">>  mov  r,c</span></font></div> <div align="left"><font face="Arial" color="#7f0000"><span style="font-size:10pt">> </span></font></div> <div align="left"><font face="Arial" color="#7f0000"><span style="font-size:10pt">> r = a + b;</span></font></div> <div align="left"><font face="Arial" color="#7f0000"><span style="font-size:10pt">> r = a | b;</span></font></div> <div align="left"><font face="Arial" color="#7f0000"><span style="font-size:10pt">> r = a || b;</span></font></div> <div align="left"><font face="Arial" color="#7f0000"><span style="font-size:10pt">>  mov  c,a</span></font></div> <div align="left"><font face="Arial" color="#7f0000"><span style="font-size:10pt">>  orl    c,b</span></font></div> <div align="left"><font face="Arial" color="#7f0000"><span style="font-size:10pt">>  mov  r,c</span></font></div> <div align="left"><font face="Arial" color="#7f0000"><span style="font-size:10pt">> </span></font></div> <div align="left"><font face="Arial" color="#7f0000"><span style="font-size:10pt">> r = a * b;</span></font></div> <div align="left"><font face="Arial" color="#7f0000"><span style="font-size:10pt">> r = a / b;</span></font></div> <div align="left"><font face="Arial" color="#7f0000"><span style="font-size:10pt">> r = a & b;</span></font></div> <div align="left"><font face="Arial" color="#7f0000"><span style="font-size:10pt">> r = a && b;</span></font></div> <div align="left"><font face="Arial" color="#7f0000"><span style="font-size:10pt">>  mov  c,a</span></font></div> <div align="left"><font face="Arial" color="#7f0000"><span style="font-size:10pt">>  anl   c,b</span></font></div> <div align="left"><font face="Arial" color="#7f0000"><span style="font-size:10pt">>  mov  r,c</span></font></div> <div align="left"><font face="Arial" color="#7f0000"><span style="font-size:10pt">> </span></font></div> <div align="left"><font face="Arial" color="#7f0000"><span style="font-size:10pt">> r = a >> b;</span></font></div> <div align="left"><font face="Arial" color="#7f0000"><span style="font-size:10pt">>  mov  c,a</span></font></div> <div align="left"><font face="Arial" color="#7f0000"><span style="font-size:10pt">>  jnb   b,.exit</span></font></div> <div align="left"><font face="Arial" color="#7f0000"><span style="font-size:10pt">>  clr    c</span></font></div> <div align="left"><font face="Arial" color="#7f0000"><span style="font-size:10pt">> .exit:</span></font></div> <div align="left"><font face="Arial" color="#7f0000"><span style="font-size:10pt">>  mov  r,c</span></font></div> <div align="left"><font face="Arial" color="#7f0000"><span style="font-size:10pt">> </span></font></div> <div align="left"><font face="Arial" color="#7f0000"><span style="font-size:10pt">> Bernhard</span></font></div> <div align="left"><br/></div> <div align="left"><font face="Arial"><span style="font-size:10pt">So have we agreed that bit behaves like a C99 _Bool?</span></font></div> <div align="left"><br/> </div> <div align="left"><font face="Arial"><span style="font-size:10pt">And if so, does anyone have a clue how C99 promotes a _Bool to an (unsigned) integer? I guess 0 (false) will be 0U, but will 1 (true) become 1U or -1U ? Apparently SDCC currently converts 1(true) to 1U.</span></font></div> <div align="left"><br/> </div> <div align="left"><font face="Arial"><span style="font-size:10pt">If it should be -1U these are the results:</span></font></div> <div align="left"><font face="Arial"><span style="font-size:10pt"> r = ~a will behave like r = !a (as many expected?).</span></font></div> <div align="left"><font face="Arial"><span style="font-size:10pt"> r = a << b and r = a >> b behave equally (who wants this anyway?)</span></font></div> <div align="left"><br/> </div> <div align="left"><font face="Arial"><span style="font-size:10pt">And the optimal code for r = a >> b is like r = a & !b</span></font></div> <div align="left"><font face="Arial"><span style="font-size:10pt"> mov     c,b</span></font></div> <div align="left"><font face="Arial"><span style="font-size:10pt"> cpl      c</span></font></div> <div align="left"><font face="Arial"><span style="font-size:10pt"> anl      c,a</span></font></div> <div align="left"><font face="Arial"><span style="font-size:10pt"> mov     r,c</span></font></div> <div align="left"><br/></div> <div align="left"><font face="Arial" color="#7f0000"><span style="font-size:10pt">> Since "bit" is not defined by the C standard, its implementation</span></font></div> <div align="left"><font face="Arial" color="#7f0000"><span style="font-size:10pt">> varies between various 8051 C compilers. I experimented with a number</span></font></div> <div align="left"><font face="Arial" color="#7f0000"><span style="font-size:10pt">> of other compilers today (like SDCC, their documentation is not as</span></font></div> <div align="left"><font face="Arial" color="#7f0000"><span style="font-size:10pt">> explicit as it should be about this language extension). Keil's C51</span></font></div> <div align="left"><font face="Arial" color="#7f0000"><span style="font-size:10pt">> and Raisonance's RC-51 treats "bit" as a boolean type. Hi-Tech's</span></font></div> <div align="left"><font face="Arial" color="#7f0000"><span style="font-size:10pt">> 8051-C treats "bit" as an unsigned int with a width of 1. It seems</span></font></div> <div align="left"><font face="Arial" color="#7f0000"><span style="font-size:10pt">> that none of these perform integer promotion on bit operands (except</span></font></div> <div align="left"><font face="Arial" color="#7f0000"><span style="font-size:10pt">> during assignment).</span></font></div> <div align="left"><font face="Arial" color="#7f0000"><span style="font-size:10pt">> </span></font></div> <div align="left"><font face="Arial" color="#7f0000"><span style="font-size:10pt">>   Erik</span></font></div> <div align="left"><br/></div> <div align="left"><font face="Arial"><span style="font-size:10pt">What exact experiments did you do? I have access to an IAR compiler and they consider C99 conformance a high priority. I would like to compare the results.</span></font></div> <div align="left"><br/></div> <div align="left"><br/> </div> <div align="left"><font face="Arial"><span style="font-size:10pt">Greets,</span></font></div> <div align="left"><font face="Arial"><span style="font-size:10pt">Maarten</span></font></div> </body> </html> |
From: Erik P. <epe...@iv...> - 2004-06-20 16:55:08
|
On Sun, 20 Jun 2004, Maarten Brock wrote: > So have we agreed that bit behaves like a C99 _Bool? > And if so, does anyone have a clue how C99 promotes a _Bool to an > (unsigned) integer? I guess 0 (false) will be 0U, but will 1 (true) > become 1U or -1U ? Apparently SDCC currently converts 1(true) to 1U. ISO/IEC 9899:1999 6.2.5 says that the "type _Bool and the unsigned integer types that correspond to the standard signed integer types are the standard unsigned integer types." > > Since "bit" is not defined by the C standard, its implementation > > varies between various 8051 C compilers. I experimented with a number > > of other compilers today (like SDCC, their documentation is not as > > explicit as it should be about this language extension). Keil's C51 > > and Raisonance's RC-51 treats "bit" as a boolean type. Hi-Tech's > > 8051-C treats "bit" as an unsigned int with a width of 1. It seems > > that none of these perform integer promotion on bit operands (except > > during assignment). > > > >=A0=A0 Erik > What exact experiments did you do? I have access to an IAR compiler and > they consider C99 conformance a high priority. I would like to compare > the results. I looked at the generated code for a number of functions. It was=20 certainly not an exhaustive test. bit b; char c; void char2bit (void) { b =3D c; /* Keil C51 & Raisonance RC-51 behave like b =3D c ? 1 : 0 (bits */ /* are boolean), whereas Hi-Tech 8051-C behaves like b =3D c & 1 */ /* (bits are unsigned:1) */ } void compBit (void) { b =3D ~b; /* Hi-Tech 8051-C rejects ~ as an bad operator for a bit; */ /* hence, integer promotion of the bit is not being performed. */ /* The others treat this as b =3D !b */ } void compBit2char (void) { c =3D ~b; /* Keil C51 & Raisonance RC-51 behave like c =3D !b; hence, */ /* integer promotion of the bit is not being performed. */ } void compCastBit2char (void) { c =3D ~((char)b); /* With the explicit cast, all three work as expected */ } void doubleBit (void) { b =3D b + b; /* Hi-Tech 8051-C generates b =3D !b ? b : !b, which results */ /* in b =3D 0 (a partial optimization consistent with the */ /* doubleBit2char and char2bit results). Raisonance RC-51 */ /* behaves like b =3D b | b. Keil C51 rejects + as a bad */ /* operator for a bit. */ } void doubleBit2char (void) { c =3D b + b; /* Hi-Tech 8051-C behaves like c =3D (char)b + (char)b. */ /* Raisonance RC-51 behaves like c =3D b | b. */ } void addBit2char (void) { c =3D c + b; /* Hi-Tech 8051-C and Raisonance RC-51 behave like */ /* c =3D c + (char)b. Keil C51 still rejects + as a bad */ /* operator. */ } I just tried the addition tests today, with the surprise results that Hi-Tech 8051-C and Raisonance RC-51 will do integer promotion on bit types for at least some cases. If SDCC treats "bit" as "_Bool", we will at least have a coherent standard to follow. Erik |
From: Bernhard H. <ber...@be...> - 2004-06-20 20:52:54
|
> ISO/IEC 9899:1999 6.2.5 says that the "type _Bool and the unsigned integer > types that correspond to the standard signed integer types are the > standard unsigned integer types." Fine. It seems to be quite clear what the standard wants. Therefore I'm now going to fix all these operations (and bug #974835). Of course I'll try to avoid promotion for the most important operations. I've got a low-priority RFE: sdcc allows the modifiers 'signed' and 'unsigned' together with the data type 'bit': signed bit sb; unsigned bit ub; I suggest that sdcc throws an error on 'signed bit'. I'm sure nobody really wants this. The question is, if 'unsigned bit' should be valid. Bernhard P.S.: Maarten, please don't use HTML formatted emails. |
From: Maarten B. <sou...@ds...> - 2004-06-22 08:50:15
|
> > On Sun, 20 Jun 2004, Maarten Brock wrote: > > > So have we agreed that bit behaves like a C99 _Bool? > > And if so, does anyone have a clue how C99 promotes a _Bool to an > > (unsigned) integer? I guess 0 (false) will be 0U, but will 1 (true) > > become 1U or -1U ? Apparently SDCC currently converts 1(true) to 1U. > > ISO/IEC 9899:1999 6.2.5 says that the "type _Bool and the unsigned > integer types that correspond to the standard signed integer types are > the standard unsigned integer types." > Yes, I read that. But does that mean I have to apply the next sentence whe= n converting _Bool to int? ISO/IEC 9899:1999 6.3.1.3 1 "When a value with integer type is converted t= o another integer type other than _Bool, if the value can be represented by the new = type, it is unchanged." > > > Since "bit" is not defined by the C standard, its implementation > > > varies between various 8051 C compilers. I experimented with a > > > number of other compilers today (like SDCC, their documentation is > > > not as explicit as it should be about this language extension). > > > Keil's C51 and Raisonance's RC-51 treats "bit" as a boolean type. > > > Hi-Tech's 8051-C treats "bit" as an unsigned int with a width of > > > 1. It seems that none of these perform integer promotion on bit > > > operands (except during assignment). > > > > > >=A0=A0 Erik > > What exact experiments did you do? I have access to an IAR compiler > > and they consider C99 conformance a high priority. I would like to > > compare the results. > > I looked at the generated code for a number of functions. It was > certainly not an exhaustive test. > > bit b; > char c; > > void char2bit (void) > { > b =3D c; > /* Keil C51 & Raisonance RC-51 behave like b =3D c ? 1 : 0 (bits */ /* > are boolean), whereas Hi-Tech 8051-C behaves like b =3D c & 1 */ /* > (bits are unsigned:1) */ IAR 5.5: b =3D c & 1 IAR 6.1: b =3D c ? 1 : 0 > } > > void compBit (void) > { > b =3D ~b; > /* Hi-Tech 8051-C rejects ~ as an bad operator for a bit; */ /* > hence, integer promotion of the bit is not being performed. */ /* > The others treat this as b =3D !b */ IAR 5.5: b =3D !b IAR 6.1: b =3D 1 > } > > void compBit2char (void) > { > c =3D ~b; > /* Keil C51 & Raisonance RC-51 behave like c =3D !b; hence, */ > /* integer promotion of the bit is not being performed. */ IAR 5.5: c =3D !b IAR 6.1: c =3D ~(char)b > } > > void compCastBit2char (void) > { > c =3D ~((char)b); > /* With the explicit cast, all three work as expected */ IAR 5.5: c =3D !b (cast is ignored!) IAR 6.1: c =3D ~(char)b > } > > void doubleBit (void) > { > b =3D b + b; > /* Hi-Tech 8051-C generates b =3D !b ? b : !b, which results */ > /* in b =3D 0 (a partial optimization consistent with the */ > /* doubleBit2char and char2bit results). Raisonance RC-51 */ > /* behaves like b =3D b | b. Keil C51 rejects + as a bad */ > /* operator for a bit. */ IAR 5.5 crashes on this one IAR 6.1: b =3D b | b > } > > void doubleBit2char (void) > { > c =3D b + b; > /* Hi-Tech 8051-C behaves like c =3D (char)b + (char)b. */ > /* Raisonance RC-51 behaves like c =3D b | b. */ IAR 5.5 crashes on this one IAR 6.1: c =3D (char)b + (char)b > } > > void addBit2char (void) > { > c =3D c + b; > /* Hi-Tech 8051-C and Raisonance RC-51 behave like */ > /* c =3D c + (char)b. Keil C51 still rejects + as a bad */ > /* operator. */ IAR 5.5: c =3D c + (char)b IAR 6.1: c =3D c + (char)b > } > > I just tried the addition tests today, with the surprise results that > Hi-Tech 8051-C and Raisonance RC-51 will do integer promotion on bit > types for at least some cases. If SDCC treats "bit" as "_Bool", we > will at least have a coherent standard to follow. I fully agree. > I've got a low-priority RFE: sdcc allows the modifiers 'signed' and > 'unsigned' together with the data type 'bit': > > signed bit sb; > unsigned bit ub; > > I suggest that sdcc throws an error on 'signed bit'. I'm sure nobody > really wants this. The question is, if 'unsigned bit' should be valid. In my opinion: no. But what does the standard say about signed _Bool or un= signed _Bool? > P.S.: Maarten, please don't use HTML formatted emails. I hope my mailer behaves a bit better now. I don't want/need HTML in my ma= il. |