Beyond Brown

When brown just isn't enough

gcc 7.1 for Ataris - return of the brown

Eventually it just had to be done.

But we didn’t expect it’d be done so soon or be so easy!

A new gcc for the ST series so soon? Why?

First of all, we don’t dictate the pace of gcc releases, the gcc consortium is responsible for that. But we did ask the question ourselves: “Why bother trying a new version at all? Aren’t newer gcc versions crap anyway (because ____ said that ____ said that he saw some generated assembly and it was simply crap?“. And we probably wouldn’t have bothered much.

But here is where some of the overhead and tools we made when building gcc 6.2 paid off: brownbot (based on Matt Godbolt’s excellent compiler explorer) was there and would happily host a new gcc alongside with the old ones. It doesn’t even need libraries if you don’t include them in your code. This was excellent since building gcc itself is not a big problem - the most time consuming part is building the libraries and dealing with all sorts of errors.

So we agreed that if we build gcc 7.1 barebones and run it through brownbot alongside with older gcc versions, comparing sources (brownbot actually supports that). If we could see a justifiable difference in code quality we’d proceed in building a full package.

You can try this yourself too. Just open brownbot, click on the disk icon and load the “c2p” example. Open two compiler windows and set one to “m68k-ataribrown-gcc” and the other to “m68k-ataribrowner-gcc” (yes, “ataribrowner” is the designated name for 7.1. It was decided on a whim). Add the following options to both compilers (the text box next to the compiler drop down selector): “-fomit-frame-pointer -O2 -m68000”. Now hover the mouse over line 32, which is the inner loop (plane loop) and you’ll notice that some lines in both compiler windows will be highlighted in bold. This is the code generated for the loop. You’ll notice the following:

gcc 7.1         gcc 6.2
-------         -------
tst.w %d4       tst.w %d4
jlt .L4         jlt .L9
move.l %d3,%a0  move.l %d3,%a0
move.w %d4,%d2  move.w %d4,%d2
...             ...
dbra %d2,.L5    cmp.w #-1,%d2
                jne .L10

So wait, is that a… dbra there? Wha-hey, cool!

And that (and a couple other quick tests) was all it took for us to delve deeper and build the rest.

Bigger, browner build

And so it was time to dust off our awesome build script that does it all automatically. At least on our setups. People did report that had some hiccups trying to use it to build their custom versions. Some provided some suggestions and patches to the script (which we are very grateful), some never reported back.

One of the things that bothered most people was the hardcoded path to /usr. It seems people are a bit less gung ho compared to us when it comes to linux! This has been addressed now, you just have to edit the script to change the install path to wherever you like and also unset sudo so no root priviledges are needed anymore. Also you can parallelise the build to use as many cores as you like. Unfortunately we’re not that great at shell scripting so we didn’t use fancy inputs or whatever else so you’ll need to change a couple of lines from the script prior to running (not a huge deal of course but it has to be done like this for now. Patches welcome of course!).

Two other issues we had during 6.2 builds were the extra % sign needed in register names when writing in gnu as and the leading underscores to symbol names which is quite crucial when linking against libraries. Here we did have some correspondance with Vincent Rivière who sent a quite comprehensive message (thanks!) with some suggestions about these issues. Back in the beginning of the year we decided against backpatching gcc 6.2 with these options because we did not want to have 2 different versions of the same gcc with different switches, as this could have led to much confusion. So instead we thought of holding everything back until version 7 was out.

Both proposed fixes are inside binutils, both leading underscores and extra percent signs. So we made a few tests with these. Unfortunately we could not get the extra % option to be properly enabled, nor we could pass it as a configuration switch so we left that out. Also we encountered some cases where even with the correct switch enabled an extra % would be required. Then we considered the leading underscore fix but eventually we agreed that just adding -fleading-underscore in gcc isn’t that big of a deal, so we skipped that too.

After that was settled we went ahead and built all libraries including mintlib. This went surprisingly smooth, with only some hiccups encountered during libstdc++v3 - after a couple of days of O_o’ing this was thankfully fixed.

So around the middle of May we had a fully working gcc 7.1 toolchain, which was (all things considered) hassle free! Also considering that the official release happened in the 2nd of May we would say that we were extremely quick :).

Brownout

Here is another point where our time spent developing 6.2 infrastructure paid off: we needed to change absolutely nothing in our elf->prg converter in order to get 7.1 running. It simply worked.

We did get quite a bit of feedback regarding brownout - how it should have been integrated inside binutils linker or how we could have used some other tools already out there. We simply claimed ignorance or thought that this would be the easiest way to go at the time. And also making such a tool ourselves means that we can fix it or extend it at will without having to cater for multiple platforms - this is a specialised ST and compatibles tool and that’s how it’s going to remain.

Brownmac

A slight tangent from the main project (but an important one) was getting our favorite assembler, rmac, to output ELF object files. Granted, gnu as and vasm already do that but it felt wrong to compromise and not use the tools we trust and are accustomed to. It took a few tries but now it’s perfectly ok to use rmac for your assembly code! (git source code repository link)

Browntran (?)

While (re)building stuff we thought we’d enable Fortran support just for fun. Surprisingly enough it actually compiled ok! Then we took some time to get Fortran’s library to compile so that’s also done. Sadly when it comes to the linking stage there still seems to be an issue with leading underscores between the library and the compiled object. We haven’t been able to solve this, but if there is any interest at all we’ll take another look!

How to build stuff using gcc 7.1

That was actually the lowest point in the 6.2 release - it was shipped without any example projects! And building something without prior knowledge of the toolchain isn’t something straightforward it probably put people off. But we sat down and rectified the situation - bigbrownbuild repository now comes with a “barebones” folder that shows how to build a few simple projects. We provide a barebones makefile and a .bat file for Windows users who hate makefiles!

As mentioned above the prefix for gcc 7.1 and tools is m68k-ataribrowner-elf-. You can always build a custom version with the prefix changed but that’s how we’re shipping it. Go wild!

The short version is: In order for the build to be succesfull brownboot.o has to be linked first, then browncrti.o, browncrt++.o, zerolibc.o, zerocrtfini.o, then your object files and all required libraries and finally browncrtn.o. Again you’re free to experiment and/or make your own mini libs if this looks too convoluted for you!

Migrating from 6.2 to 7.1

If you already have projects running on 6.2, switching to 7.1 in our experience was as easy as changing compiler and library paths. When we tried it in our projects everything went so smoothly that we consider the 6.x line of gcc a thing of the past! So don’t be afraid to start using 7.1 - in fact we delayed its release to make absolutely sure it works properly.

Get it or build it

In contrast to last time we decided to provide binaries for Windows only and let the other platforms build their own versions.

Mercurial bigbrownbuild repository is over here - clone it or download a zip file. Just run bigbrownbuild.sh, edit the script for install path and/or build cores and run it. Hopefully you will get a set of binaries ready to deploy! Optionally edit and run _postinstall.sh to arrange libraries in a more sane way (have a look at the 6.2 article for more explanations). Make sure you only run it once and that it points to the right directories! (linux users will probably want to change /lib/ to /usr/lib)

Mercurial brownout repository is over here. It should be a simple matter of running buildit.sh or compiling it via Visual Studio.

Brownbot

As mentioned above brownbot has been updated to contain all 7.1 compilers and libraries. It’s mostly self explanatory so just visit the site and experiment!

A big brown thanks

Thanks to the following individuals for expressing their interest and providing feedback:

  • Patrice Mandin
  • Vincent Rivière
  • Elias Mårtenson
  • Miro Kropáček
  • Troed Sångberg

If you want to get in touch with us you can use DHS coding bbs or leave a comment in bigbrownbuild repository.

We hope we have fun with this even browner gcc!

Updates

16/07/2017: Troed Sångberg very kindly provided a mac build! Head over to this site to download. Note that it hasn’t been extensively tested, just got the barebones examples compiling ok.