>> Eddie Starling wrote: >>> I'm looking for an inexpensive C compiler for PIC processors. Has >>> anybody had any experience with the CCS compiler. I'm looking atthe >>> 14 bit compiler (PCM). Are there any others worth considering. >... and Dag Bakken replied: >> You should have a look at the CC5X C-Compiler. This compiler >> supports the 12-bit and 14-bit PIC core. ... and Andrew Warren replied : > But not the 16-bit core. ... and myself (Dag Bakken) replied again : That is correct >> This is (as far as I know) the oldest PIC C-compiler available (i.e >> very well debugged). > While the compiler itself has very few real bugs, the libraries included > with it (which are the most compelling reason for anyone to buy the > compiler) often DO have serious bugs... New revisions of those libraries > seem not to be tested very well by CCS before they're released. Not that I'm trying to be difficult, but I'm talking about the CC5X C-compiler... Not the CCS compiler. This is an entirely different product. (I have both of them...) >> CC5X will also generate the most compact code, and reuses RAM >> whenever possible. This is the main advantage of this compiler. >> When most compilers have filled up your ROM, CC5X may be able to >> generate the same program in 2/3 of the space. > It's important to note that: > 1) CCS doesn't use any high-powered optimization algorithms or > anything... CC5X does... > The compactness of their generated code is due almost entirely to the > fact that the compiler only supports a "Baby-C" subset, limited to the > operations that are DIRECTLY supported by the PIC instruction set. CC5X also uses a C-subset. > 16-bit math, for example, is not directly supported; in fact, the > compiler doesn't even support SIGNED math. This is also true for CC5X > 2) The CCS compiler doesn't really generate code that's all THAT > compact, anyway. true... > Here's a simple example of optimization failure: > byte1 = x; > byte2 = x; > byte3 = x; > In this case, the compiler produces: > movf x,w > movwf byte1 > movf x,w > movwf byte2 > movf x,w > movwf byte3 > The trivial optimization that the compiler misses is, of course: > movf x,w > movwf byte1 > movwf byte2 > movwf byte3 This is the same piece of code compiled with CC5X : MOVF x,W MOVWF byte1 MOVWF byte2 MOVWF byte3 > "A-ha!" you say, "But what if 'x' is an I/O port? In THAT case, the > optimized code might be inaccurate." > Well, ok... But shouldn't a compiler written specifically for the PIC > know the difference between an I/O port and a general-purpose file > register? I mean, really... This is the same piece of code with 'x' as an I/O port (again, compiled with CC5X) : MOVF PORTB,W MOVWF byte1 MOVF PORTB,W MOVWF byte2 MOVF PORTB,W MOVWF byte3 > Besides, when the compiler's given: > byte1++; > it compiles it to: > movf byte1,w > incf byte1 > What's up with THAT? ...and CC5X generated : INCF byte1,1 >> The most frequent question from customers, is how to implement >> inline assembly... This is something that is not possible, and you >> don't need it. > You DO need it, and it IS possible... To write inline assembly, just > bracket your assembly code with #ASM and #ENDASM directives. I do agree with you on this one. With CCS you do need it. With CC5X you don't. > I know that Eddie didn't want to spend a lot of money, but if anyone > else on the list is looking for a "real" C compiler, I recommend MPC > and MPLAB-C. Well... They are supposed to be ANSI compatible, but they are not. Even the MPLAB-C help-file says that MPLAB-C is not ANSI compatible. - These compilers can't assign single bits in RAM to a variable without addressing the byte where they are located. When you're working with a lot of flags, this doesn't actually help you. - I'm not quite sure about the latest version, but the other versions did only support static variables. i.e RAM re-use is equal to nothing. - Code optimization is terrible, but getting better... One "bug" that I found in MPLAB-C was this : STATUS.GIE=1; ... and the compiler accepted it! If you want to do something to any bit with CC5X, you can : GIE=1; ... and CC5X does the rest. You can even do this on your own variables : bit x; // allocate a single bit in RAM x=1; // use it you do not need to know where it is. This action will only occupy a single bit. You can do this : bit x,y,z; // allocate three bits in RAM If there is a RAM location with as much as three free bits in it, they will be used for this. If not, a new byte will be used. If you allocate these bits as local in a function, the same byte used for the bits will be re-used in another function for something else (of course). Dag Bakken