CC65 vs OSDK ?

Since we do not have native C compilers on the Oric, this forum will be mostly be used by people using CC65 or the OSDK. But any general C related post will be welcome !
User avatar
Dbug
Site Admin
Posts: 4437
Joined: Fri Jan 06, 2006 10:00 pm
Location: Oslo, Norway
Contact:

CC65 vs OSDK ?

Post by Dbug »

So far we had no really significant set of data allowing us to efficiently compare the quality of CC65 compared to the C compiler used in the OSDK.

Interesting comparison points are:
- ANSI compatibility
- Size of generated code
- Speed of generated code

I guess I could try to recompile Contiki using the OSDK, but I need to get hold of the Oric port of Contiki project, if somebody (carlsson ?) can provide me with explanation on how to build a working Oric Contiki, I will try this week end to see if it can be made also with the OSDK.

Perhaps we could also run some standard benchmarks :D
User avatar
carlsson
Pilot Officer
Posts: 127
Joined: Thu Jan 12, 2006 11:26 pm
Location: Västerås, Sweden

Post by carlsson »

http://www.cbm.sfks.se/files/contiki-1_0atmos.tar.gz

This is version 1.0 of Contiki (similar to the preview I posted). It should compile out of the box with most recent cc65 and Make utility: make atmos. Compared to the official version, I made the following changes:

* Added an entry for Atmos in the root directory Makefile
* Created make/Makefile.atmos which could be extended (see C64 makefile) to compile in uIP support or some more applications if you wish
* Made some changes in /arch/cc65/ctk-conio.h for Oric key codes. Those should be in the Atmos cc65 library, but alas not yet..

There is no need for an atmos.cfg file, as I rely on the default memory model supplied with the compiler. As mentioned in the other thread, a bit more memory than default could be utilized depending on whether HIRES graphics are used or not etc.

A few warnings appear during the compile phase, in particular one about petsciiconv_toascii called without a function prototype, or rather that function is #defined to nothing for systems that don't use PETSCII.
Anders Carlsson
User avatar
carlsson
Pilot Officer
Posts: 127
Joined: Thu Jan 12, 2006 11:26 pm
Location: Västerås, Sweden

Post by carlsson »

On Fabrice's page, there is a links to the gcc port for 65C02 by Dave MacWherter:

http://oric.ifrance.com/oric/software.html

That compiler makes sixteen 24 bit registers in zeropage. Ullrich von Bassewitz reviewed it on cc65 mailing list in year 2000, and came to the conclusion it has many limitations and would not be very feasible for 6502 programming, but maybe you have other opinions?

From Mickael's description in the other thread, it sounds like the lcc port RCC16 as used in ODSK compiles code for a 16 bit virtual machine and then macros to execute each virtual instruction? If you compare code output from these lcc and gcc ports, is there any difference? The gcc port was based on 2.7.2 which is several years old, but I remember was rather reliable until the 2.95 merge with ecgs.

Maybe any compiler originally designed for a larger computer has to take this approach when it is down scaled. On the other hand, cc65 is originally based on a Small C implementation for 6502 and then improved upon, so it has always been targetted directly at the 6502 platform.
Anders Carlsson
User avatar
Dbug
Site Admin
Posts: 4437
Joined: Fri Jan 06, 2006 10:00 pm
Location: Oslo, Norway
Contact:

Post by Dbug »

From what I tested so far, it seems that CC65 generates a way better code than RCC16.

Could you put the generated assembly source code as a download somewhere so I can do an accurate comparison of how CC65 and RCC16 compiles stuff ?

Just for the fun, I tried to put the output of RCC16 through "opt65", a peephole optimized. The generated assembled code reduced from 42k to 35k... but unfortunately didn't run at all (I suspect this is because of all the "bxx *+n" that now jumps in between reordered instructions).

Just to be sure, I checked the documentation of CA65, and I cannot use that for my own assembly projects. I hate the syntax, the local labels and scopes are horrible, I love the sheer simplicity of XA.

I guess I could try to find a way to use XA as a back-end for CC65, perhaps converting the source code...
User avatar
carlsson
Pilot Officer
Posts: 127
Joined: Thu Jan 12, 2006 11:26 pm
Location: Västerås, Sweden

Post by carlsson »

http://www.cbm.sfks.se/files/contiric-cc65s.tar.gz

I have never used ca65 for my own assembly code, I use Dasm. Many people who have got accustomed with it find it superior though. I see why you would like to make a software development kit with only one assembler, but if the compiler generates good code that is hard to translate to another assembler format, maybe including two assemblers would be an idea.

I'll have a look at the library supplied with OSDK and compare to the assembly source code that makes up for the cc65 Atmos library. Some of the system specific features in the OSDK are of course non-existant, some are not yet implemented and some may have a different implementation.

For example, in cc65 there is a hack for write() made to enable printf. This hack directly calls $F77C (PRINT) for each character, rather than going via $0238 (the print vector, if I understand correctly). Not sure if either way is better than the other, but in the OSDK implementation, you have support for lprintf by swapping the vector, call printf and swap the vector back. Also, cc65 reads the keyboard directly via LDA $02DF but OSDK does JSR $023B. Putchar is implemented with a call to $0238 in OSDK but written directly to screen memory in cc65. Depending on how the functions are used and linked, I suppose a bit of further improvement and increased support could be achieved by looking over this by someone with a good knowledge about the target platform (here: Oric Atmos).
Anders Carlsson
User avatar
Euphoric
Game master
Posts: 99
Joined: Mon Jan 09, 2006 11:33 am
Location: France

Post by Euphoric »

From what I tested so far, it seems that CC65 generates a way better code than RCC16.
I depends on what you mean by "better" code...
Rcc16 generates faster code than cc65, at the expense of bigger code. This is mostly due to the fact cc65 uses JSR calls to load operands whereas rcc16 uses a sequence of instructions to load operands into virtual registers.

Just tried a classical Eratosthene sieve program:

Code: Select all

/* Eratosthenes Sieve benchmark */
#define size 10000
char flags[10000];

extern int printf(char *format,...);

int main()
{
    int i, prime, k, count=0;

    for(i=0;i<size;i++)
        if (!flags[i]) {
            prime = i + i + 3;
            for (k=i+prime; k<size ; k+=prime) flags[k]=1;
            count++;
        }
	
    printf("\n%d primes\n", count);
}
cc65 is more than 2 times slower than rcc16 to compute the prime numbers (-O2 optimization level for both compilers)
About memory utilization: despite what I said about cc65 generating smaller code, for small programs cc65 has to include the routines handling the operands (those called by the JSR instructions) so the result might be inversed.
In the case of the sieve program above, the .tap image is 11359 bytes when generated by the OSDK, and 2732 bytes when generated by lc65 plus 10000 bytes of data, ie. 12732 bytes.
User avatar
Dbug
Site Admin
Posts: 4437
Joined: Fri Jan 06, 2006 10:00 pm
Location: Oslo, Norway
Contact:

Post by Dbug »

There is a domain in which RCC16 can be improved thus, it's the handling of 8 bits values.

I wonder how CC65 deals with that, but at least RCC16 backend generates lots of 16 bits operations for what is only 8 bits values.
User avatar
Euphoric
Game master
Posts: 99
Joined: Mon Jan 09, 2006 11:33 am
Location: France

Post by Euphoric »

There is a domain in which RCC16 can be improved thus, it's the handling of 8 bits values.

I wonder how CC65 deals with that, but at least RCC16 backend generates lots of 16 bits operations for what is only 8 bits values.
Unfortunately, it's not the backend that generates those 16 bits operations, but the frontend instead. The C standard says that every integer operation promotes its operands to int values (or long when int's are too small). The RCC frontend strictly complies to this promotion...

The most annoying thing with RCC (at least with the old 1.9 version I used), is that int's and long's are the same size. For a small platform like the 6502, I would love to build a C compiler that has 8-bits int's, and 16-bits long's :-) ... but this is not possible with RCC.
User avatar
carlsson
Pilot Officer
Posts: 127
Joined: Thu Jan 12, 2006 11:26 pm
Location: Västerås, Sweden

Post by carlsson »

From what I gather, char is 8 bits, int is 16 bits and long is 32 bits in cc65.

http://www.cc65.org/doc/coding.html

By the way, -O2 is ignored by cc65. You may want to try -Oi for inlining as much as possible. In the case of Sieve, wouldn't it make sense to allocate the array dynamically (calloc/free) and reduce 10K from the executable? :?:

There is a Sieve sample program included with cc65. It sets #pragma staticlocals and defines a few variables as register (-Or). I'm not sure if it improves speed and/or code size anything.
Anders Carlsson
jede
Flying Officer
Posts: 191
Joined: Tue Mar 14, 2006 11:53 am
Location: France

Post by jede »

carlsson wrote:
I have never used ca65 for my own assembly code, I use Dasm. Many people who have got accustomed with it find it superior though. I see why you would like to make a software development kit with only one assembler, but if the compiler generates good code that is hard to translate to another assembler format, maybe including two assemblers would be an idea.
I used ca65, but as Dbug, i prefer a lot XA. Xa could be improved but, the C code in XA is a bit hard to undestand, because, variables have strange name
mmu_man
Flight Lieutenant
Posts: 322
Joined: Thu Sep 21, 2006 7:45 pm
Location: 26000 Valence, FRANCE
Contact:

Post by mmu_man »

cc65 has a BeOS port working out of the box, so... :)
Ok I could probably port OSDK too...
JamesD
Flight Lieutenant
Posts: 358
Joined: Tue Nov 07, 2006 7:38 am

Post by JamesD »

int should be 16 bit, not 8 bit. If you want to use 8 bits use char. If you don't like calling it char, typedef byte and use that.
The 6809 port of GCC uses 8 bit int's and it kills portability. The author added a command line flag to let you select 8 or 16 bit int's after enough people complained.
JamesD
Flight Lieutenant
Posts: 358
Joined: Tue Nov 07, 2006 7:38 am

Post by JamesD »

BTW, if lcc doesn't have a decent peephole optimizer you should take a look at SDCC's source. It has a pretty good peephole optimizer based on pattern matching and it would be easy to implement optimizations for lcc/rcc16 if you were to extract the optimizer code and make it standalone.
Post Reply