On gcc defines and consistency

09 Oct 2006 • 2 min read

Builtin defines from gcc are useful - they give you some information about your arch. __i386__, __amd64__ and so on.

sparc is a little wierd - here's a quick list

  • __sparc__
  • __sparc64__
  • __sparc_v9__

Now, FreeBSD only supports Sparc64 and has lots of checks using #ifdef __sparc64__. At first glance, this looks OK and there appears to be nothing wrong with it. However, gcc likes to define __sparc64__ as a CPU type (as I understand it) and is no guarantee of 64-bit code. As such, if you use -mcpu=ultrasparc (which is valid) then it drops the __sparc64__ define as we're targeting a specific CPU model - namely the v9. A FreeBSD developer submitted a gcc patch to always define __sparc64__ but this was rejected, and looks like for good reasons too.

Of course, we can always say "dude, don't use -mcpu in your CFLAGS" and the issue magically goes away. Not so! In gcc-4, FreeBSD defaults to using -mcpu=ultrasparc which means that it never defines __sparc64__ which in turn means a vanilla gcc cannot compile FreeBSD code! Which explains why the default compiler on FreeBSD is gcc-3.4.6. Interesting we cannot use that version in Gentoo as our 3.4.6 never exports the __arch64__ define (or any other 64-bit defines) but still compiles 64-bit code. Weird. Anyway, our gcc-4.1.1 is fine for us.

So I'm busy writing patches to change __sparc64__ to __sparc__ as most of the time the code isn't 64-bit specific anyway. If it is, then it becomes __sparc__ && __arch64__ which works fine 😃 I dunno if upsteam will accept it, but I'll email it to them anyway when I'm done 😛