1Fermer3
Lionel DebrouxLe 22/11/2011 à 20:18
Hi Erik smile

You're not the first person to mention the making of a standard toolchain, usable with standard build systems and development tools, targetting TI-68k calculators. The idea has already floated several times in other places of community, during the past year smile


If you want to make something easier to update to newer versions of GCC+binutils, it's clear that you should stay away from the GCC4TI patches to the compiler and binutils. They're huge, and contain platform-specific changes for a couple dozens of areas, mixed up into a single patch (well, two: one for GCC, one for binutils).
I once spent a couple hours partitioning the GCC patch, see the raw result at the end of the post.

However, there's a rationale for pretty much every single platform-specific change, and very few of the changes of the patchsets are unwanted. Some hunks revert backwards-incompatible changes in upstream GCC, so they obviously couldn't have been pushed upstream, but a number of important improvements might have been usefully pushed upstream at some point...
One of the rationales for having a platform-specific linker is backwards compatibility with AmigaOS files, but the linker does much more than this - for instance, special linker builtins for controlling various aspects of the linking, or the entire startup code handling (which makes maintenance of the equivalent of crt0.s much easier), and more.

Also noteworthy is the fact that support for generic m68k COFF was removed from GCC in GCC 4.4: http://gcc.gnu.org/gcc-4.4/changes.html , so ELF is the way forward for GCC 4.6+. With good linker scripts, we can think that ELF could do the job smile

Finally, if I get this working, would GCC4TI be interested in me contributing the work back, or would it become yet another TI M68K compiler?

Well, I'm not refusing the principle, but I'm afraid that the amount of possible sharing between a clean standard ELF-based toolchain, based on recent tool versions, and a mass of platform-specific changes and platform-specific COFF-based tools, would be slim... I'd accept being proved wrong, though smile


Two general notes:
* toolchains for other comparable calculator models (HPGCC for HP-49G+ family calculators, the Ndless development kit for Nspires, the third-party Casio Prizm development kits) don't have such huge patches to the toolchain, so many platform-specific changes, and such a messy build system (though GCC4TI's is slightly better than that of TIGCC). Probably a bad thing for ease of program development and backwards compatibility (as a user, I appreciate some of the silly changes of upstream GCC having been reverted), but a clear boon to maintenance.

* for building cross-compilation toolchains, I know of crosstool-ng. And I'm told by someone I trust that devkitpro is quite a good example of a cross-platform toolchain.



First pass on splitting gcc-4.1-tigcc-patch constituents (needs more work):
* win32 changes: config.guess, gcc/config/i386/xm-mingw32.h, gcc/gcc.c, libcpp/files.c
* fiddling with default attributes: gcc/attribs.c, gcc/c-common.c, gcc/c-common.h, gcc/c-decl.c, gcc/c-lang.c, gcc/c-tree.h, gcc/langhooks-def.h, gcc/langhooks.h, gcc/system.h
* changes to the GCC built-in functions, among which is __builtin_ER_throw: gcc/builtin-attrs.def, gcc/builtins.c, gcc/builtins.def
* stkparm / regparm parameter passing: gcc/builtins.c, gcc/c-decl.c, gcc/config/m68k/m68k.c, gcc/config/m68k/m68k.h, gcc/config/m68k/m68k-protos.h, gcc/c-parser.c, gcc/c-tree.h, gcc/function.c, gcc/function.h
* SMAP II BCD support: gcc/c-cppbuiltin.c, gcc/c-format.c, gcc/combine.c, gcc/config/m68k/m68k.md, gcc/config/m68k/m68k-modes.def, gcc/config/m68k/predicates.md, gcc/config/smapbcd.h, gcc/config.gcc, gcc/convert.c, probably gcc/c-pretty-print.c, gcc/dwarf2out.c, gcc/emit-rtl.c, probably gcc/explow.c, gcc/expr.c, gcc/final.c, gcc/fold-const.c, gcc/genmodes.c, gcc/machmode.def, gcc/optabs.c, gcc/output.h, gcc/print-rtl.c, gcc/print-tree.c, gcc/real.c, gcc/real.h, gcc/rtlanal.c, gcc/simplify-rtx.c, gcc/tree.c, gcc/tree-pretty-print.c, gcc/varasm.c
* global cast constructors / compound literals: gcc/c-decl.c, gcc/common.opt, gcc/flags.h, gcc/varasm.c
* -fno-function-cse changes: gcc/cfgexpand.c, gcc/gimplify.c, gcc/tree-ssa-dom.c, gcc/tree-ssa-pre.c
* kill global include paths, usage of environment variables, hard-coded prefixes, etc.: gcc/c-incpath.c, gcc/c-opts.c, gcc/cppdefault.c, gcc/gcc.c
* changes related to forward or backslashes in paths: gcc/c-incpath.c, gcc/toplev.c
* multi-line strings: probably gcc/c-lex.c, probably gcc/c-ppoutput.c, libcpp/internal.h, libcpp/lex.c
* constant pools, section merging, moving stuff between bss/data/rodata: gcc/common.opt, gcc/config/m68k/m68k.c, gcc/config/m68k/m68k.h, gcc/config/m68k/m68k.md, gcc/config/m68k/m68k-none.h, gcc/config/m68k/m68k.opt, gcc/config/m68k/m68k-ti.h, gcc/flags.h, gcc/varasm.c
* register-relative addressing & global register variables: gcc/common.opt, gcc/config/m68k/m68k.c, gcc/config/m68k/m68k.h, gcc/config/m68k/m68k.md, gcc/final.c, gcc/gcse.c, gcc/ifcvt.c, gcc/opts.c
* default to not initializing the BSS section: gcc/common.opt
* debugging support: maybe gcc/config/dbxcoff.h, gcc/config/m68k/m68k.c, gcc/dwarf2.h, gcc/dwarf2out.c, gcc/toplev.c, gcc/varasm.c
* OPTIMIZE_ROM_CALLs: gcc/config/m68k/m68k.c
* no long branches: gcc/config/m68k/m68k.c + external patcher (with a "FIXME: should be moved to GCC")
* platform-specific changes such as greater optimization, or different printf/scanf/memset/etc., or peepholes: gcc/c-format.c, gcc/config/m68k/m68k.c, gcc/config/m68k/m68k.h, gcc/config/m68k/m68k.md, gcc/config/m68k/m68k-none.h, gcc/config/m68k/m68k.opt, gcc/config/m68k/m68k-ti.h, gcc/config/m68k/predicates.md, gcc/expr.c, gcc/opts.c, gcc/postreload.c, gcc/stmt.c, gcc/tree-object-size.c
* no-auto-octals: gcc/c.opt, gcc/c-opts.c, libcpp/include/cpplib.h, libcpp/init.c
* changes to default warnings: gcc/c-decl.c -> what with "Each undeclared identifier is reported only once" ?, gcc/c-opts.c
* reverting the removal of casts-as-lvalues: gcc/c-parser.c, gcc/c-typeck.c, gcc/tree.h
* gcc/c-pretty-print.c -> what's the second hunk ?
* reference the TIGCC infrastructure which does not make public the bug report content: gcc/diagnostic.c, gcc/version.c
* a warn_unused_result-related change: gcc/gimplify.c
* a patch related to using hard register variables as an asm input: gcc/loop.c
* gcc/sdbout.c -> ?
* inlining-related fix: gcc/tree-inline.c
* a change without comments in gcc/tree-ssa-ccp.c
* pragma poison (why ?): libcpp/directives.c
* binary numbers (0b...) support: libcpp/expr.c
* SYMSTR optimization: libcpp/macro.c

git / svn blame is unhelpful, need to look up in the Changelog and commit history...


Known bugs (besides being a nightmare to port forward to newer GCC versions, and not being directly portable above GCC 4.4):
* http://tichessteamhq.yuku.com/topic/4793 : in CALLBACK functions, a5 is not reinitialized to __jmp_tbl, which can yield a crash.
- N3buk4dn3zz4r: "I managed to find the reason for this special error: Using #define OPTIMIZE_ROM_CALLS causes this code to crash(who knows why?), if this option is not set, the above code should work pretty well."

- Lionel: "When OPTIMIZE_ROM_CALLS is defined, the startup code initializes the a5 processor register to the address of the ROM_CALL table, and the rest of the program uses that to read the addresses of ROM_CALLs.
However, AMS uses a5 for its own purposes in a number of functions. When AMS calls back into your program, the value of a5 can be different from what the program expects. Any CALLBACK or interrupt handler function using a5 (or, in general, any global register variable) without having reinitialized it to the expected value will trigger one of the processor exceptions when trying to call TE_handleEvent.

There are at least two fixes to the problem:
* some inline ASM for reinitializing a5;
* using F-Line ROM_CALLs, with an internal emulator if you want your program to run on AMS <= 2.03 without requiring your users to install some form of F-Line ROM_CALL handler. F-Line ROM_CALLs are smaller than optimized ROM_CALLs (potentially large savings on programs containing many ROM_CALLs), but have some overhead in the call/return sequence (not that it matters much in practice)."

- Kevin: "To fix this properly, we need to have CALLBACK expand to a dedicated GCC attribute, add that attribute to GCC, and then add a similar hack to GCC's config/m68k/m68k.c to what we already have for interrupt handlers (__attribute__((interrupt_handler))), search for OPTIMIZE_ROM_CALLS in the TIGCC patch or the TIGCC-patched config/m68k/m68k.c."
(it's not just OPTIMIZE_ROM_CALLS, Kevin - all global register variables are affected by this infrequent problem, i.e. -freg-relative-a<n> and other user-defined global register variables are affected, though we can't do much for the latter)