CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to support@ccsinfo.com

Simple C Syntax " |= " not working

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
Franck26



Joined: 29 Dec 2007
Posts: 122
Location: Ireland

View user's profile Send private message

Simple C Syntax " |= " not working
PostPosted: Fri Jan 18, 2008 3:30 am     Reply with quote

Hi everybody,
I was wondering what is the difference between this 2 lines:
Code:
*xBufEvent = *xBufEvent | 0x01;

and
Code:
*xBufEvent |= 0x01;


For me they have to do the same thing but the second one is not doing anything...

Thanks for any reply,
Franck.
Ttelmah
Guest







PostPosted: Fri Jan 18, 2008 4:09 am     Reply with quote

Hm.
It generates correct code in either case for me...
What compiler version?.
The simple version, generates (fo a 16chip):
Code:

....................    *xBufEvent |= 0x01;
006C:  MOVF   2D,W
006D:  MOVWF  04
006E:  BCF    03.7
006F:  BTFSC  2E.0
0070:  BSF    03.7
0071:  MOVF   00,W
0072:  IORLW  01
0073:  MOVWF  00


Which (in this case xBufEvent is stored in location '0x2D', and '0x2E'), puts the contents of 2D, into the indirect addressing register, uses the contents of 2E to set the page register, then retrieves the byte addressed by these, bitwise OR's it with 1, and writes it back.

While for a 18F chip, it generates:
Code:

....................    *xBufEvent |= 0x01;
00E4:  MOVFF  1C,FE9
00E8:  MOVFF  1D,FEA
00EC:  MOVF   FEF,W
00EE:  IORLW  01
00F0:  MOVWF  FEF


Which again is correct (xBufEvent is stored here in 1C/1D).
The same correct code, is generated by 3.249, and 4.066 compilers.
There is a 'caveat' about this type of statement, in that it is preferred, and safer, to use:

(*xBufEvent) |= 0x01;

since otherwise there an be precedence problems with some commands a the '*' (this is mentioned in K&R, at a couple of places), but this shouldn't apply with what you post.

Best Wishes
Franck26



Joined: 29 Dec 2007
Posts: 122
Location: Ireland

View user's profile Send private message

PostPosted: Fri Jan 18, 2008 6:51 am     Reply with quote

Thanks for your reply,
I'm using PCD 4.066 for a pic24H.

I hyaven't had a look of the asm code that my compiler have generated Embarassed .

I will check that this night.

Thanks.
John P



Joined: 17 Sep 2003
Posts: 331

View user's profile Send private message

PostPosted: Fri Jan 18, 2008 10:10 am     Reply with quote

I tried this just for fun using my ancient compiler, adding it as a line in an existing program using a variable that I already had defined. I'm utterly puzzled by this result. My variable is at 0x57, but what's all this use of 0x37 and 0x38? I don't get it at all.

But I'm certain that the quickest way to do what Franck wanted would be

Code:

bit_set(*xBufEvent, 0);


Code:

0000                03116 ....................    *cons0 = *cons0 | 0x01;
0726 0857           03117 MOVF   57,W
0727 1683           03118 BSF    03,5
0728 00B7           03119 MOVWF  37
0729 1283           03120 BCF    03,5
072A 0857           03121 MOVF   57,W
072B 0084           03122 MOVWF  04
072C 0800           03123 MOVF   00,W
072D 3801           03124 IORLW  01
072E 1683           03125 BSF    03,5
072F 00B8           03126 MOVWF  38
0730 0837           03127 MOVF   37,W
0731 0084           03128 MOVWF  04
0732 0838           03129 MOVF   38,W
0733 0080           03130 MOVWF  00
0734 1283           03131 BCF    03,5
Ttelmah
Guest







PostPosted: Fri Jan 18, 2008 10:36 am     Reply with quote

Temporary variables.
It takes the contents of 57, and temporarily stores it in 37. Then writes it to the indirect addressing register. Takes the location addressed by this, and performs the OR, stores the result of this into 38, then brings back the temporary value in 37, and again writes this to the address register, and writes to result from 38, to the addressed location.
Effectively it treats it as two halves (because of the layout), and performs the right hand part first, to the temporary registers, then the left hand part using the values from this.
I must admit, I'd not be suprised if there was a problem with this on the 24F chips. Read the comments here about V4, and realise it took CCS, a year to actually produce a reasonably 'working' V4. Then think how long support for the 24F chips has existed. At present, it is closer to working than V4 was at the same point, but I'd definately consider the 16bit compiler to be 'beta'...

Best Wishes
Franck26



Joined: 29 Dec 2007
Posts: 122
Location: Ireland

View user's profile Send private message

PostPosted: Fri Jan 18, 2008 2:02 pm     Reply with quote

OK, shame on me, it was that my watches were not refresh on time with my debugger Embarassed ...

But I still have the same kind of problem...
This code is working:
Code:
static unsigned int _FCT_EV_Mask;
void SetEvent(unsigned int *xBufEvent, unsigned int NumEvent)
{
   _FCT_EV_Mask = 1;
   _FCT_EV_Mask <<= NumEvent;
   (*xBufEvent) |= _FCT_EV_Mask;
}


And this one not:
Code:

static unsigned int _FCT_EV_Mask;
void SetEvent(unsigned int *xBufEvent, unsigned int NumEvent)
{
   _FCT_EV_Mask = 1;
   (*xBufEvent) |= (_FCT_EV_Mask << NumEvent);
}


In fact I wanted to use the second one cos I've noticed in the lst file of the first one that the code is not very efficient : the result of "_FCT_EV_Mask <<= NumEvent" is put from W0 to _FCT_EV_Mask and put back from _FCT_EV_Mask to W0...

The asm code of the first one which is working:
Code:
void SetEvent(unsigned int *xBufEvent, unsigned int NumEvent)
{
*
00200:  MOV     W5,[W15++]     : Push W5 to TOS
..............................    _FCT_EV_Mask = 1;
00202:  MOV     #1,W4          : W4 = 1
00204:  MOV     W4,85C         : [85C] = W4
..............................    _FCT_EV_Mask <<= NumEvent;
00206:  MOV     872,W4         : W4 = [872]
00208:  MOV     85C,W0         : W0 = [85C]
0020A:  SL      W0,W4,W0       : W0 = W0 << W4
0020C:  MOV     W0,85C         : [85C] = W0
..............................    (*xBufEvent) |= _FCT_EV_Mask;
0020E:  MOV     870,W5         : W5 = [870]
00210:  MOV     [W5],W0        : W0 = [W5]
00212:  IOR     85C,W0         : W0 = [85C] | W0
00214:  SUB.B   W5L,#2,W5L     : W5L = W5L - 2
00216:  MOV.B   W5L,[W5]       : [W5] = W5L
00218:  MOV.B   #0,W0L         : W0L = 0 
0021A:  MOV.B   W0L,[W5+#0]    : [W5+0] = W0L
.............................. }
0021C:  MOV     [--W15],W5     : POP TOS to [--W15]
0021E:  RETURN                 : Return


And the asm code of the second one which is NOT working:
Code:
void SetEvent(unsigned int *xBufEvent, unsigned int NumEvent)
{
*
00200:  MOV     W5,[W15++]     : Push W5 to TOS
..............................    _FCT_EV_Mask = 1;
00202:  MOV     #1,W4          : W4 = 1
00204:  MOV     W4,85C         : [85C] = W4
..............................    (*xBufEvent) |= (_FCT_EV_Mask<<NumEvent);               
00206:  MOV     870,W5         : W5 = [870]
00208:  MOV     872,W4         : W4 = [872]
0020A:  MOV     85C,W0         : W0 = [85C]
0020C:  SL      W0,W4,W0       : W0 = W0 << W4
0020E:  IOR      W0,  [W5],W0  : W0 = W0 | [W5]
00210:  SUB.B   W5L,#2,W5L     : W5L = W5L - 2
00212:  MOV.B   W5L,[W5]       : [W5] = W5L
00214:  MOV.B   #0,W0L         : W0L = 0 
00216:  MOV.B   W0L,[W5+#0]    : [W5+0] = W0L
.............................. }
00218:  MOV     [--W15],W5     : POP TOS to [--W15]
0021A:  RETURN                 : Return
}


Did someone have an idea why this 2 codes are not doing the same thing?

And I haven't catch what is the purpose of this line:
Code:
00210:  SUB.B   W5L,#2,W5L     : W5L = W5L - 2


Thanks for any helps,
Franck.
Bob Sacamano



Joined: 17 Jan 2008
Posts: 16
Location: Somewhere Cold, USA

View user's profile Send private message

PostPosted: Fri Jan 18, 2008 2:18 pm     Reply with quote

The two code snippets are not the exact same thing. In the first one, _FCT_EV_Mask has it's value updated after left-shifting. In the second one, the variable will never be updated, it will only be used in determining the value to store at xBufEvent.

What exactly is happening that is wrong?

Can you post a small, complete, compilable example program that shows the error. Include what you expect the results to be and what they actually are.
_________________
"And you want to be my latex salesman."
Franck26



Joined: 29 Dec 2007
Posts: 122
Location: Ireland

View user's profile Send private message

PostPosted: Sat Jan 19, 2008 9:26 am     Reply with quote

Thanks for your reply,
I've found what was my problem, it was the pointer.
It seems that the compiler is not doing the same thing for this 2 lines of codes:

Code:
(*ptrResult) |= Mask;

is not the same that
Code:
(*ptrResult) = (*ptrResult) | Mask;


The first code is changing only the pointer, and the second one is changing the variable pointed by ptrResult (it's what I wanted).

I don't know if it's a bugg in the compiler or if it's normal...
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group