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 CCS Technical Support

int1 = val&1 optimization possible?

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



Joined: 30 Oct 2014
Posts: 4

View user's profile Send private message

int1 = val&1 optimization possible?
PostPosted: Thu Oct 30, 2014 8:14 pm     Reply with quote

I notice in my code that this compiles to:
.................... int1 b = (crc & 1);
17E4: MOVF 27,W
17E5: ANDLW 01
17E6: MOVWF 77
17E7: CLRF 7A
17E8: BCF 29.0
17E9: BTFSC 77.0
17EA: BSF 29.0

Since I'm doing an &1 on the outside you could just do this:
17E4: MOVF 27,W
17E5: ANDLW 01
17E6: MOVWF 29

PCM Compiler v5.030
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Thu Oct 30, 2014 9:04 pm     Reply with quote

Post a short, compilable test program that shows the PIC and all variable declarations.
Example:
Code:

#include <16F886.h>
#fuses INTRC_IO, NOWDT
#use delay(clock=4M)

//============================
void main()
{
int8 crc = 0x55;
int1 b = (crc & 1);


while(TRUE);
}
matt.dawson



Joined: 30 Oct 2014
Posts: 4

View user's profile Send private message

PostPosted: Thu Oct 30, 2014 10:19 pm     Reply with quote

That's exactly it.
I've tested this in PCM Compiler v5.030, compiling at optimisation level 9 and it generates the same extra bit clears, tests and sets.

Code:

#include <16LF1705.h>

void main() {
    int8 a = 15;
    int1 b = a&1;
    for(;;);
}


Generates:
Code:

.................... void main() {
// Removed irrelevant bits here //
0008:  MOVLW  0F
0009:  MOVWF  21
000A:  MOVF   21,W
000B:  ANDLW  01
000C:  MOVWF  78
000D:  BCF    22.0
000E:  BTFSC  78.0
000F:  BSF    22.0
....................     int8 a = 15;
....................     int1 b = a&1;
....................     for(;;);
0010:  GOTO   010
.................... }
Ttelmah



Joined: 11 Mar 2010
Posts: 19587

View user's profile Send private message

PostPosted: Fri Oct 31, 2014 1:40 am     Reply with quote

The code is performing a cast automatically.

Think about it. The & solution, would directly work, if and only if b is the bottom bit of the storage location used.
The 'int8' result of the operation 'crc&1', has to be converted to be an 'int1' solution, so it can set any bit in the target. This is what the compiler is doing.

Try the & solution, with b being the second bit in the value. What happens?.
Then look at the compiler's solution. Does it work?.

Then try with b declared as an int8. What does the compiler generate?.
matt.dawson



Joined: 30 Oct 2014
Posts: 4

View user's profile Send private message

PostPosted: Fri Oct 31, 2014 2:32 am     Reply with quote

Yes I understand why it's done in the generic case.
The case I'm talking about is an optimization for when the last operation in an expression is a constant and of 1.
It isn't hard to detect that in a parser tree.

>> edit

Also in the case where it's 2, it can be done with a shift.
Or 4 with 2 shifts. I'm just suggesting an optimization.
Ttelmah



Joined: 11 Mar 2010
Posts: 19587

View user's profile Send private message

PostPosted: Fri Oct 31, 2014 2:44 am     Reply with quote

You don't have a constant. You have a variable.
The solution has to be able to cope with anything.

If you declare crc as a constant, the compiler optimises to just setting the bit without any test at all.
matt.dawson



Joined: 30 Oct 2014
Posts: 4

View user's profile Send private message

PostPosted: Fri Oct 31, 2014 2:55 am     Reply with quote

In "a & 1", 1 is a constant.
Optimized paths don't have to handle everything, they are chosen based upon the specific code written.
Ttelmah



Joined: 11 Mar 2010
Posts: 19587

View user's profile Send private message

PostPosted: Fri Oct 31, 2014 8:31 am     Reply with quote

Yes, '1' is a constant, but 'a' is not.
Ttelmah



Joined: 11 Mar 2010
Posts: 19587

View user's profile Send private message

PostPosted: Mon Nov 03, 2014 1:29 am     Reply with quote

as a comment to this, realise that the casting takes place because the operation 'a & 1', is using 8bit arithmetic, and returns an 8bit value.
The compiler operation 'bit_test', instead returns a true/false value, and therefore doesn't involve the cast:
Code:

    int1 b = bit_test(a,0);
000A:  BCF    22.0
000B:  BTFSC  21.0
000C:  BSF    22.0

Which will work for any bit in source or destination, and is the most efficient 'general' solution available.
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