GCC processor

If you wish to improve the code generated by GCC, or know that you will be compiling for a specific machine or range of processors, there are several options that will be of interest when using GCC for RISC OS. What's mentioned here is relevant both to the native released RISC OS binary and the cross compiler.

Default Target
To be of general use, the distribution GCC defaults to producing code that runs on a broad range of RISC OS machines, GCC produces APCS-32 code that will run on ARM6 or above. That is, code that will work on RiscPC machines or later, and does not make use of any special instructions found on later processors. Binaries and libraries bundled with GCC (in particular, UnixLib) are also compiled in this manner.

What's important to remember here is that for code to be suitable for a given machine, the program and any libraries it is linked with must be compiled for a processor which is compatible with it. GCC can produce ARM2 code, however that sacrifices some performance, and very few RISC OS machines in use today have such a processor. The choice of ARM6 is therefore a balance against performance and machines in use today.

Default Tuning
Tuning is the choice of instructions the compiler chooses to output to minimise load delays and produce the best performing code it can within the choice of instructions for the target that is in use. GCC's default tuning is for XScale - this gives the best all-round performance, especially for XScale and StrongARM targets. This can be modified with the '-mtune' flag.

Processor Choices
There is a processor choice that is the best for every single RISC OS machine. However, to avoid explosion of choice, and to focus only on the main groups of machines in use, this is split into 4 main groups.

ARM3/apcs26
Although GCC can be instructed to produce code for this ('-mapcs26 -mcpu=arm3'), the default UnixLib is not compiled for this processor and support for this is depredicated. For GCCSDK 3.4, this requires a custom build with appropriate options. There is no support for APCS-26 and ARM3 anymore in the GCCSDK 4 releases.

RiscPC/A7000 class machines
Including ARM6/ARM7/StrongARM RiscPCs, A7000/A7000+, Mico and RiscStation. ARM6 RiscPCs are really the odd one out here, since all the others have at least an ARM7. More specifically, ARMv3m, which includes the newer instructions like UMULL, which can improve performance for certain computational operations. If you want to include ARM6, then the default GCC with no options is correct. Otherwise, use '-march=armv3m -mtune=strongarm'.

StrongARM class machines
Including StrongARM RiscPC (all StrongARM revisions including Kinetic), Omega and A9home. These correspond to ARMv4. Again, the RiscPC is the odd one out here, since its I/O architecture cannot handle 16-bit operations even though the processor supports them. Note that the Kinetic I/O hardware does support the 16-bit operations but as it is not possible to predict if Kinetic RAM or the onboard RiscPC RAM is going to be used it is not possible to use the half-word operations on RiscPC at all. So '-mcpu=strongarm' will work for these machines.

XScale class
This only includes the IOP321 IYONIX pc for now, but because there are specific applications for some of its hardware and because many of the most active RISC OS users have one and it includes a number of extra instructions, this deserves a class of its own. For this, use '-mcpu=xscale'.

GCC can also generate thumb code which will work on this machine, but this is not very interesting for RISC OS. In addition, GCCSDK has a configuration option to generate an XScale-specific GCC/UnixLib which will produce code by default only suitable for XScale machines. Such a build of UnixLib contains initialisation code which will provent it being accidentally run on non-XScales.

GCC defines
For each of the options, GCC will set preprocessor flags, to allow conditional compilation of code specific to a processor.

(More detail here)

Assembler flags
Also, GCC will pass the processor type to its assembler (using the -t flag, which is compatible with Acorn C/C++ objasm). This is used to check that any assembler passed to GCC - including assembler it generates itself, inline assembly, and normal assembler files - do not contain instructions that are not suitable for the target processors. The assembler will also set the TARGET_CPU variable which can be used for processor-specific code.