View previous topic :: View next topic |
Author |
Message |
Franck26
Joined: 29 Dec 2007 Posts: 122 Location: Ireland
|
Define and asm code |
Posted: Tue Mar 10, 2009 9:24 am |
|
|
Hello,
To optimize a code I try to implement this define:
Code: | #define SetEvent(x,y) #if y<8 #asm BSF x,y #endasm #else #asm BSF x+1,(y-8) #endasm #endif |
x is an int16 variable and y a constant (0 to 15).
What I want to do is to set the bit y of the variable x.
I've got the error "Expecting an opcode mnemonic" if y>7.
Code: | unsigned int16 TEST_Event;
TEST_Event = 0;
SetEvent(TEST_Event, 2); // OK
SetEvent(TEST_Event, 10); // Error: Expecting an opcode mnemonic |
Do you have any idea how to implement this define?
Thanks for any help,
Franck.
Compiler CCS 4.083. |
|
|
Sydney
Joined: 13 Feb 2009 Posts: 71
|
|
Posted: Tue Mar 10, 2009 11:10 am |
|
|
Am I missing something, or are you?
Code: | unsigned int16 TEST_Event;
TEST_Event = 0;
bit_set(TEST_Event, 2); // OK
bit_set(TEST_Event, 10); // OK |
|
|
|
Sydney
Joined: 13 Feb 2009 Posts: 71
|
|
Posted: Tue Mar 10, 2009 11:13 am |
|
|
Code: | .................... unsigned int16 TEST_Event;
.................... TEST_Event = 0;
2002: CLRF xC6
2004: CLRF xC5
.................... bit_set(TEST_Event, 2); // OK
2006: BSF xC5.2
.................... bit_set(TEST_Event, 10); // OK
2008: BSF xC6.2 |
|
|
|
RLScott
Joined: 10 Jul 2007 Posts: 465
|
Re: Define and asm code |
Posted: Tue Mar 10, 2009 11:13 am |
|
|
There is no reason to mess around with that macro. Just use:
Code: |
bit_set(TEST_Event,2);
bit_set(TEST_Event,10);
|
The compiler is smart enough to convert each of these to the one instruction that your macro was trying to do. Try it and look at the resulting .LST file to see what I mean.
Ha, Sydney, you beat me to it! _________________ Robert Scott
Real-Time Specialties
Embedded Systems Consulting |
|
|
Franck26
Joined: 29 Dec 2007 Posts: 122 Location: Ireland
|
|
Posted: Tue Mar 10, 2009 12:08 pm |
|
|
Thanks for your answer,
It's true that it's the easiest way to do it...
I've just forgot to precise that I would like to keep the code compatible with other PIC compiler than CCS. I should have say that earlier...
Other idea?
Thanks for your help. |
|
|
FvM
Joined: 27 Aug 2008 Posts: 2337 Location: Germany
|
|
Posted: Tue Mar 10, 2009 12:16 pm |
|
|
In this case you can use bit_set() in your macro for CCS with a version dependant conditional compile.
The capabilities of CCS C to understand certain asm constructs seems somewhat arbitrary, B.T.W. |
|
|
Sydney
Joined: 13 Feb 2009 Posts: 71
|
|
Posted: Tue Mar 10, 2009 12:18 pm |
|
|
Code: | .................... unsigned int16 TEST_Event;
.................... TEST_Event = 0;
1FA4: CLRF xC6
1FA6: CLRF xC5
.................... TEST_Event |= 1 << 2; // OK
1FA8: BSF xC5.2
.................... TEST_Event |= 1 << 10; // OK
1FAA: BSF xC6.2 |
|
|
|
Franck26
Joined: 29 Dec 2007 Posts: 122 Location: Ireland
|
|
Posted: Wed Mar 11, 2009 5:19 am |
|
|
Hi,
OK, I'll make a conditional compile dependent on the version.
That's pity that
Code: | #define SetEvent(x,y) #if y<8 #asm BSF x,y #endasm #else #asm BSF x+1,(y-8) #endasm #endif |
is not understood by CCS, it would be cleaner and portable ...
Thanks for your help,
Franck. |
|
|
Ttelmah Guest
|
|
Posted: Wed Mar 11, 2009 8:37 am |
|
|
The 'x+1' syntax, would not be understood by CCS anyway.
Assembler like this, is never going to be 'portable'. CCS uses CCS assembler, Microchip, use Microchip assembler, HiTech, use HiTech assembler. etc.. All have differences.
CCS, treats the name of a variable in assembler, as if it is the address of the variable, and allows the 'shortcut', of using the name as a target. To address the next byte, the syntax is actually &x+1. If you try the two assembler lines without the if statement, this is the syntax needed to make the second one work.
Moving between any language, is going to require different syntaxes. If you want to write this as a 'portable construct', then have a define at the start of your code, saying what complier you are working on, and a include file containing the different defines to work for the various compilers so something like:
Code: |
#ifdef CCS
#define SetEvent(x,y) bit_set(x,y)
#elif MicroChip
#define SetEvent(x,y) #if y<8 #asm BSF x,y #endasm\
#else #asm BSF x+1,(y-8) #endasm #endif
#endif
|
You will have to do a lot of syntax tweaking though, including redefining the variable name/sizes etc..
Best Wishes |
|
|
Sydney
Joined: 13 Feb 2009 Posts: 71
|
|
Posted: Wed Mar 11, 2009 1:44 pm |
|
|
What was the matter with my method, will work on any c compiler? :( |
|
|
Franck26
Joined: 29 Dec 2007 Posts: 122 Location: Ireland
|
|
Posted: Wed Mar 11, 2009 3:22 pm |
|
|
Hello Sydney,
Your method would work with any C compiler but it's not sure that it would be optimised.
The compiler could generate a loop to shift a mask and it would increase the executive time.
Your test show that CCS compiler is enough clever to avoid that .
Thanks for your help,
Franck. |
|
|
Sydney
Joined: 13 Feb 2009 Posts: 71
|
|
Posted: Wed Mar 11, 2009 3:44 pm |
|
|
True, I was suprised it did compile to 2 instruction actually |
|
|
|