GCC processor

From RISC OS
Revision as of 05:06, 23 August 2006 by Pnaulls (talk | contribs)
Jump to navigationJump to search

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 binary and the GCCSDK 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 libaries it is linked with must be compiled for a processor which is compatible with it. GCC can produce ARM2 code, however that sacrificies 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. This requires a custom build of GCCSDK with appropriate options (more details to come)

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.

StrongARM class machines

Including StrongARM RiscPC (all StrongARM revisions including Kinetic), Omega and A9. 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. -mcpu=strongarm will work for these machines.

XScale class

This only includes the IOP321 Iyonix 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.