SH4 in Compiler Explorer: Difference between revisions
No edit summary |
GyroVorbis (talk | contribs) No edit summary |
||
(18 intermediate revisions by the same user not shown) | |||
Line 4: | Line 4: | ||
[[File:SH4 Compiler Explorer Configuration.png|thumb|SH GCC Toolchain configured for the Dreamcast's SH4 CPU in Compiler Explorer]] | [[File:SH4 Compiler Explorer Configuration.png|thumb|SH GCC Toolchain configured for the Dreamcast's SH4 CPU in Compiler Explorer]] | ||
To arrive at a configuration mirroring a Dreamcast development environment, first select one of the GCC compiler versions for the SH architecture. Secondly, the following compiler options should be used as the baseline configuration: | To arrive at a configuration mirroring a Dreamcast development environment, first select one of the GCC compiler versions for the SH architecture. Secondly, the following compiler options should be used as the baseline configuration: | ||
* -ml: | * <code>-ml</code>: compile code for the processor in little-endian mode | ||
* -m4-single-only: | * FPU Mode: | ||
* -ffast-math: | ** <code>-m4-single-only</code>: generate code for the SH4 with a floating-point unit that only supports single-precision floating point arithmetic | ||
* -O3: optimization level 3 | ** <code>-m4-single</code>: generate code for the SH4 with a floating-point unit that supports both single and double-precision floating point arithmetic that defaults to single-precision mode upon function entry | ||
* -mfsrra: enables emission of the fsrra instruction for reciprocal square root approximations. | * <code>-ffast-math</code>: breaks strict IEEE compliance and allows for faster floating point approximations | ||
* -mfsca: enables emission of the fsca instruction for sine and cosine approximations | * <code>-O3</code>: optimization level 3 | ||
* <code>-mfsrra</code>: enables emission of the fsrra instruction for reciprocal square root approximations (not available in GCC 4.7.4) | |||
* <code>-mfsca</code>: enables emission of the fsca instruction for sine and cosine approximations (not available in GCC 4.7.4) | |||
* <code>-matomic-model=soft-imask</code>: enables support for C11 and C++11 atomics by disabling then reenabling interrupts around atomic variable operations | |||
* <code>-ftls-model=local-exec</code>: enables the model used by KOS for supporting variables declared with the "thread_local" keyword | |||
= Convenience Templates = | = Convenience Templates = | ||
[[File:GCC Compiler Benchmarks.png|thumb|Runtime performance and binary sizes for different GCC versions using various compiler flags on KOS's pvrmark example.]] | [[File:GCC Compiler Benchmarks.png|thumb|Runtime performance and binary sizes for different GCC versions using various compiler flags on KOS's pvrmark example: [https://dcemulation.org/phpBB/viewtopic.php?p=1059978#p1059978 Source]]] | ||
The following are pre-configured templates you can use as sample Dreamcast build configurations: | The following are pre-configured templates you can use as sample Dreamcast build configurations: | ||
* GCC4.9.4: | * GCC4.9.4: | ||
Line 26: | Line 30: | ||
** [https://godbolt.org/z/Kb9bKe8ro C2X Hello World] | ** [https://godbolt.org/z/Kb9bKe8ro C2X Hello World] | ||
** [https://godbolt.org/z/51dv4ePsG C++23 Hello World] | ** [https://godbolt.org/z/51dv4ePsG C++23 Hello World] | ||
* GCC13.2.0: | |||
** [https://godbolt.org/z/rafvMdWGb C2X Hello World] | |||
** [https://godbolt.org/z/MeG3rqna7 C++23 Hello World] | |||
* GCC 14.1.0 | |||
** [https://godbolt.org/z/7ha8oj4vd C23 Hello World] | |||
** [https://godbolt.org/z/eW8Yd8sG9 C++26 Hello World] | |||
Pre-configured template for ARM GCC8.5, Dreamcast's "AICA" sound chip: | |||
* [https://godbolt.org/z/895dWG9qf C Hello World] | |||
= Tips and Notes = | = Tips and Notes = | ||
* It has been noted that while -O3 is claimed to be the highest optimization level according to recent GCC documentation, some code differences can still be seen under certain circumstances when using -O4 and beyond. | * It has been noted that while <code>-O3</code> is claimed to be the highest optimization level according to recent GCC documentation, some code differences can still be seen under certain circumstances when using <code>-O4</code> and beyond. | ||
* The compiler seems to ignore both -mfsrra and -mfsca without the -ffast-math and -m4-single-only options. | * The compiler seems to ignore both <code>-mfsrra</code> and <code>-mfsca</code> without the <code>-ffast-math</code> and <code>-m4-single-only</code> options. | ||
* It is highly recommended that C code is written to use -mfsrra (1.0/sqrt(N)) and -mfsca (builtin sin/cos) over using inline assembly directly, as this seems to give the compiler more context for code optimization around these instructions. | * It is highly recommended that C code is written to use <code>-mfsrra</code> (1.0/sqrt(N)) and <code>-mfsca</code> (builtin sin/cos) over using inline assembly directly, as this seems to give the compiler more context for code optimization around these instructions. | ||
* The __builtin_prefetch intrinsic does seem to generate a single "pref" instruction and should be preferred over inline assembly. | * The <code>__builtin_prefetch</code> intrinsic does seem to generate a single "pref" instruction and should be preferred over inline assembly. | ||
* The compiler does not seem smart enough to utilize the FIPR (inner/dot product), FMAC (multiply and accumulate), or FTRV (transform vector) instructions regardless of how embarrassingly vectorizable the supplied C code seems to be, so linear algebra routines are forced to use inline assembly to fully leverage the SH4's SIMD instructions. | * The compiler does not seem smart enough to utilize the FIPR (inner/dot product), FMAC (multiply and accumulate), or FTRV (transform vector) instructions regardless of how embarrassingly vectorizable the supplied C code seems to be, so linear algebra routines are forced to use inline assembly to fully leverage the SH4's SIMD instructions. | ||
* Typically smaller code sizes and more tightly optimized code are seen with newer versions of GCC versus the older ones; however, this is not always the case. | * Typically smaller code sizes and more tightly optimized code are seen with newer versions of GCC versus the older ones; however, this is not always the case. | ||
* Evidently, even without a branch predictor, the C++20 <nowiki>[[likely]]</nowiki> and <nowiki>[[unlikely]]</nowiki> attributes as well as the GCC intrinsic __builtin_expect() can have a fairly profound impact on code generation and optimization for conditionals and branches. More information can be found [https://dcemulation.org/phpBB/viewtopic.php?t=106029 here]. | * Evidently, even without a branch predictor, the C++20 <code><nowiki>[[likely]]</nowiki></code> and <code><nowiki>[[unlikely]]</nowiki></code> attributes as well as the GCC intrinsic <code>__builtin_expect()</code> can have a fairly profound impact on code generation and optimization for conditionals and branches. More information can be found [https://dcemulation.org/phpBB/viewtopic.php?t=106029 here]. | ||
* -fipa-pta allows the compiler to analyze pointer and reference usage beyond the scope of the current compiling function, which very often results in pretty decent performance increases at the cost of increased compile times and RAM usage. | * <code>-fipa-pta</code> allows the compiler to analyze pointer and reference usage beyond the scope of the current compiling function, which very often results in pretty decent performance increases at the cost of increased compile times and RAM usage. | ||
* -flto allows GCC to perform optimizations over the entire program and all translation units as a single entity during the linking phase, for the cost of increased compile times and RAM usage. This frequently results in more performant code. | * <code>-flto</code> allows GCC to perform optimizations over the entire program and all translation units as a single entity during the linking phase, for the cost of increased compile times and RAM usage. This frequently results in more performant code. | ||
* An in-depth benchmark comparing the run-time performance and compiled binary size output of every toolchain version officially supported by KOS with various optimization levels can be found [https://dcemulation.org/phpBB/viewtopic.php?t=106068 here]. | * An in-depth benchmark comparing the run-time performance and compiled binary size output of every toolchain version officially supported by KOS with various optimization levels can be found [https://dcemulation.org/phpBB/viewtopic.php?t=106068 here]. |
Latest revision as of 13:45, 8 May 2024
Thanks to the effort of Matt Godbolt (who hilariously enough is a former Dreamcast developer himself), the SuperH GCC toolchain is now available for use with Compiler Explorer, along with all of the SH4-specific compiler flags and options typically used when targeting the Dreamcast. This gives us an invaluable tool for getting quick and immediate feedback on how well a given C or C++ source segment tends to translate into SH4 assembly, offering a little sandbox for testing and optimizing code targeting the Dreamcast.
Configuration
To arrive at a configuration mirroring a Dreamcast development environment, first select one of the GCC compiler versions for the SH architecture. Secondly, the following compiler options should be used as the baseline configuration:
-ml
: compile code for the processor in little-endian mode- FPU Mode:
-m4-single-only
: generate code for the SH4 with a floating-point unit that only supports single-precision floating point arithmetic-m4-single
: generate code for the SH4 with a floating-point unit that supports both single and double-precision floating point arithmetic that defaults to single-precision mode upon function entry
-ffast-math
: breaks strict IEEE compliance and allows for faster floating point approximations-O3
: optimization level 3-mfsrra
: enables emission of the fsrra instruction for reciprocal square root approximations (not available in GCC 4.7.4)-mfsca
: enables emission of the fsca instruction for sine and cosine approximations (not available in GCC 4.7.4)-matomic-model=soft-imask
: enables support for C11 and C++11 atomics by disabling then reenabling interrupts around atomic variable operations-ftls-model=local-exec
: enables the model used by KOS for supporting variables declared with the "thread_local" keyword
Convenience Templates
![](/wiki/images/thumb/f/f1/GCC_Compiler_Benchmarks.png/300px-GCC_Compiler_Benchmarks.png)
The following are pre-configured templates you can use as sample Dreamcast build configurations:
- GCC4.9.4:
- GCC9.5.0:
- GCC12.2.0:
- GCC13.1.0:
- GCC13.2.0:
- GCC 14.1.0
Pre-configured template for ARM GCC8.5, Dreamcast's "AICA" sound chip:
Tips and Notes
- It has been noted that while
-O3
is claimed to be the highest optimization level according to recent GCC documentation, some code differences can still be seen under certain circumstances when using-O4
and beyond. - The compiler seems to ignore both
-mfsrra
and-mfsca
without the-ffast-math
and-m4-single-only
options. - It is highly recommended that C code is written to use
-mfsrra
(1.0/sqrt(N)) and-mfsca
(builtin sin/cos) over using inline assembly directly, as this seems to give the compiler more context for code optimization around these instructions. - The
__builtin_prefetch
intrinsic does seem to generate a single "pref" instruction and should be preferred over inline assembly. - The compiler does not seem smart enough to utilize the FIPR (inner/dot product), FMAC (multiply and accumulate), or FTRV (transform vector) instructions regardless of how embarrassingly vectorizable the supplied C code seems to be, so linear algebra routines are forced to use inline assembly to fully leverage the SH4's SIMD instructions.
- Typically smaller code sizes and more tightly optimized code are seen with newer versions of GCC versus the older ones; however, this is not always the case.
- Evidently, even without a branch predictor, the C++20
[[likely]]
and[[unlikely]]
attributes as well as the GCC intrinsic__builtin_expect()
can have a fairly profound impact on code generation and optimization for conditionals and branches. More information can be found here. -fipa-pta
allows the compiler to analyze pointer and reference usage beyond the scope of the current compiling function, which very often results in pretty decent performance increases at the cost of increased compile times and RAM usage.-flto
allows GCC to perform optimizations over the entire program and all translation units as a single entity during the linking phase, for the cost of increased compile times and RAM usage. This frequently results in more performant code.- An in-depth benchmark comparing the run-time performance and compiled binary size output of every toolchain version officially supported by KOS with various optimization levels can be found here.