View previous topic :: View next topic |
Author |
Message |
bennyboos
Joined: 17 Nov 2005 Posts: 30 Location: Chester UK
|
Compiler using FSR's unnecessarily ? |
Posted: Mon Oct 19, 2009 5:51 am |
|
|
I do not particularly like using make8(), make16() as they are CCS specific and not ANSI compliant & cannot be used in "reverse" - i.e. suppose you want to write or alter just the upper byte of an int16.
One option is to use a union (http://www.ccsinfo.com/forum/viewtopic.php?t=30416) to provide access to the individual bytes in int16 and int32's but I prefer to use a set of defines as follow:-
Code: | #define byte0(var) *((char *)&var + 0)
#define byte1(var) *((char *)&var + 1)
#define byte2(var) *((char *)&var + 2)
#define byte3(var) *((char *)&var + 3) |
These have the advantage in that you can not only read but also write the byte of any particular variable, for example:-
Code: | int bigVar = 0x1234; // Declare & initialise an int16
byte1(bigVar) = 0x56; // Set the high byte to a new value
|
Obviously this is endian-specific (can be worked around) but more importantly can lead to misuse, i.e. accessing "outside" of a particular variable (i.e. the third byte of an int16 is clearly nonsense/dangerous). I am happy to live with this since it is no different to the usual "care" one must apply when using pointers in 'C'.
Anyway - my gripe is that the compiler does not "spot" that we are accessing an adjacent/neighbouring byte and instead resorts to a full-blown FSR / INDF routine to access the byte of the variable in question. If I do the same in HiTech C their compiler optimises this very efficiently down to one line without touching any FSR's. Can anyone offer any other suggestions - or have I missed an optimisation setting somewhere?
(For the record I am returning to CCS from HiTech since they are dropping their support of their standard C18 compiler which is their only compiler which supports the Salvo RTOS. CCS now has the advantage here in that they provide a built-in OS). |
|
|
FvM
Joined: 27 Aug 2008 Posts: 2337 Location: Germany
|
|
Posted: Mon Oct 19, 2009 6:35 am |
|
|
When you are using C expression as *((char *)&var + 3), there's no guarantee, that a compiler is able to understand it as simple byte access. You can expect to get a correct result, but the code may be rather long-winded. As far as I see, this is the case with CCS C. You'll find also other examples, where the CCS compiler is interpreting the C text word-by-word and generates unnecessary code.
You may want to complain about missing compiler intelligence, but if you have reasons to use CCS C anyway (there are actually a lot), then you should use constructs, that are better understood. CCS built-in functions are a good option in my opinion. Compatibility with generic C can be achieved with respective #define macro code. |
|
|
bkamen
Joined: 07 Jan 2004 Posts: 1615 Location: Central Illinois, USA
|
|
Posted: Mon Oct 19, 2009 9:46 am |
|
|
And BTW, most MCHP code does just that. They struct a BYTE or WORD or DWORD.
The 8-bit PICs always have funny math to find their offset in memory (using CCS, I don't know about C18) that you can get around with hand crafted code.
I do wish they'd optimize it. write/read_program_memory are good examples of this "unknown variable"
The command always sets up to be a loop (more code) and then if you read the same spot multiple times, it invokes that same setup again and again.
-Ben _________________ Dazed and confused? I don't think so. Just "plain lost" will do. :D |
|
|
|