10. Porting GHC

This section describes how to port GHC to a currenly unsupported platform. There are two distinct possibilities:

10.1. Booting/porting from C (.hc) files

Bootstrapping GHC on a system without GHC already installed is achieved by taking the intermediate C files (known as HC files) from a GHC compilation on a supported system to the target machine, and compiling them using gcc to get a working GHC.

NOTE: GHC version 5.xx is significantly harder to bootstrap from C than previous versions. We recommend starting from version 4.08.2 if you need to bootstrap in this way.

HC files are architecture-dependent (but not OS-dependent), so you have to get a set that were generated on similar hardware. There may be some supplied on the GHC download page, otherwise you'll have to compile some up yourself, or start from unregisterised HC files - see Section 10.2.

The following steps should result in a working GHC build with full libraries:

10.2. Porting GHC to a new architecture

The first step in porting to a new architecture is to get an unregisterised build working. An unregisterised build is one that compiles via vanilla C only. By contrast, a registerised build uses the following architecture-specific hacks for speed:

In an unregisterised build, neither of these hacks are used — the idea is that the C code generated by the compiler should compile using gcc only. The lack of these optimisations costs about a factor of two in performance, but since unregisterised compilation is usually just a step on the way to a full registerised port, we don't mind too much.

10.2.1. Building an unregisterised port

The first step is to get some unregisterised HC files. Either (a) download them from the GHC site (if there are some available for the right version of GHC), or (b) build them yourself on any machine with a working GHC. If at all possible this should be a machine with the same word size as the target.

There is a script available which should automate the process of doing the 2-stage bootstrap necessary to get the unregisterised HC files - it's available in fptools/distrib/cross-port in CVS.

Now take these unregisterised HC files to the target platform and bootstrap a compiler from them as per the instructions in Section 10.1. In build.mk, you need to tell the build system that the compiler you're building is (a) unregisterised itself, and (b) builds unregisterised binaries. This varies depending on the GHC version you're bootstraping:

# build.mk for GHC 4.08.x
GhcWithRegisterised=NO
# build.mk for GHC 5.xx
GhcUnregisterised=YES

Version 5.xx only: use the option --enable-hc-boot-unregisterised instead of --enable-hc-boot when running ./configure.

The build may not go through cleanly. We've tried to stick to writing portable code in most parts of the compiler, so it should compile on any POSIXish system with gcc, but in our experience most systems differ from the standards in one way or another. Deal with any problems as they arise - if you get stuck, ask the experts on .

Once you have the unregisterised compiler up and running, you can use it to start a registerised port. The following sections describe the various parts of the system that will need architecture-specific tweaks in order to get a registerised build going.

Lots of useful information about the innards of GHC is available in the GHC Commentary, which might be helpful if you run into some code which needs tweaking for your system.

10.2.2. Porting the RTS

The following files need architecture-specific code for a registerised build:

ghc/includes/MachRegs.h

Defines the STG-register to machine-register mapping. You need to know your platform's C calling convention, and which registers are generally available for mapping to global register variables. There are plenty of useful comments in this file.

ghc/includes/TailCalls.h

Macros that cooperate with the mangler (see Section 10.2.3) to make proper tail-calls work.

ghc/rts/Adjustor.c

Support for foreign import "wrapper" (aka foreign export dynamic). Not essential for getting GHC bootstrapped, so this file can be deferred until later if necessary.

ghc/rts/StgCRun.c

The little assembly layer between the C world and the Haskell world. See the comments and code for the other architectures in this file for pointers.

ghc/rts/MBlock.h, ghc/rts/MBlock.c

These files are really OS-specific rather than architecture-specific. In MBlock.h is specified the absolute location at which the RTS should try to allocate memory on your platform (try to find an area which doesn't conflict with code or dynamic libraries). In Mblock.c you might need to tweak the call to mmap() for your OS.