View previous topic :: View next topic |
Author |
Message |
FvM
Joined: 27 Aug 2008 Posts: 2337 Location: Germany
|
New PCD bug with complemented constants |
Posted: Mon Mar 11, 2013 12:07 pm |
|
|
The bitwise inversion operator (one's complement) is often used to define inverted bitmasks to mask of specific bits. E.g. & ~1 selectively resets Bit 0. In new PCD versions, the inverted mask is only evaluated to int8 although the other operand is int16. C implicite type conversion rules require conversion of the constant to the size of the larger operand, as implemented with previous PCD versions.
PCD V4.141
Code: | .............................. int16 i;
..............................
.............................. i &= ~1;
0117E: MOV 976,W4 : W4 = [976]
01180: AND #FE,W4 : W4 = FE & W4
01182: MOV W4,976 : [976] = W4
.............................. i &= ~(int16) 1;
01184: BCLR.B 976.0 : [976.0] = 0
.............................. |
PCD V4.135
Code: | .................... i &= ~1;
01154: BCLR.B 976.0 : [976.0] = 0
.................... i &= ~(int16) 1;
01156: BCLR.B 976.0 : [976.0] = 0 |
|
|
|
asmboy
Joined: 20 Nov 2007 Posts: 2128 Location: albany ny
|
|
Posted: Mon Mar 11, 2013 7:27 pm |
|
|
OK I'll bite.
What is wrong with either of the examples?
while .141 looks awkward ,and is less code efficient,
is the result still not correct?
the logical NOT of 1 is zero isn't it ?
and only the low order bit gets zero'd
as an honest show of my ignorance, I'll go on record as saying
I'm OK with both results you show.
each is what I'd hope to get from the expression if i was coding it,
though for completeness, and ease of recalling what i did,
I might instead do the AND with
0b11111110
or ob1111111111111110 respectively.
I don't get what is at issue exactly.
Is it 'ME" or 'C' ??
|
|
|
FvM
Joined: 27 Aug 2008 Posts: 2337 Location: Germany
|
|
Posted: Tue Mar 12, 2013 12:17 am |
|
|
Quote: | I might instead do the AND with
0b11111110
or ob1111111111111110 respectively. |
Anding a word with
0b0000000011111110
or
0b1111111111111110
is not the same.
Code: | void main(void)
{
unsigned int16 test;
test = 1013;
test &= ~1;
printf("expect 1012, got %u\r\n",test);
} |
|
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19504
|
|
Posted: Tue Mar 12, 2013 1:33 am |
|
|
Key is to remember that in PCD, the default size of things is int16. So a constant _ought_ to automatically be an int16. Instead the compiler has switched to treating PCD constants as int8, and not performing the C standard operation of converting them _up_ when used in arithmetic with an int16, unless they are explicitly declared int16...
Presumably:
i &= ~1L
works, but it is a case of a really basic C rule being ignored. Duh.....
'~' is "one's complement", _not_ "logical not". It is meant to complement every bit in the value. So, the result is not 'zero'....
I haven't had a chance to load .141 yet, but what happens if (for instance), you rotate an 8bit constant, and then combine the result with an int16?.
It is not "'ME' or 'C'", it is CCS, breaking a rather fundamental rule.....
Have just put in .141.
It still doesn't work, if you select ANSI mode, which is even worse, since this assumes things to be int16 unless otherwise specified....
Explicitly using 'L' does work.
Have you reported it Fvm?.
Best Wishes |
|
|
FvM
Joined: 27 Aug 2008 Posts: 2337 Location: Germany
|
|
Posted: Tue Mar 12, 2013 1:23 pm |
|
|
Yes, I reported the issue.
I stumbled upon it when I switched my working version for several projects from V4.127 to V4.140 last week
and known good code stopped to work for me. Being alarmed, I found less obvious instances of the problem,
burried deep down in SD library code, with a good chance to reveal months after shipment at the customer's site...
Regards,
Frank |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19504
|
|
Posted: Tue Mar 12, 2013 1:59 pm |
|
|
Interesting. I'd been sticking with 4.137, on my current project, because things stopped working with 4.140. Hoped .141 would fix the problems. :(
Best Wishes |
|
|
asmboy
Joined: 20 Nov 2007 Posts: 2128 Location: albany ny
|
|
Posted: Tue Mar 12, 2013 3:02 pm |
|
|
4.135 is the last "safe" version for programs i've had to alter and recompile lately.
Do i hear a consensus that 4.137 is safer all around
for 16f /18f parts ??
re 4.141 -- oddly enough i had trouble with int1 arrays on older code
BUT did use 4.141 for messing with the 16f1509....NCO functions |
|
|
|