GCC 1.27 was released in 1988 and is the first version of GCC supporting the x86 CPU. I thought it would be fun to make it work on my desktop computer.
Mikhail Maltsev wrote a great blog post about this a while back “Building and using a 29-year-old compiler on a modern system”. I used Mikhail’s work as a starting point, but I built on a 64-bit Ubuntu system so I needed to update paths and
as
/ld
options for running on a 64-bit OS, and I had much bigger problems with the ancient GCC not understanding the system headers. I also enabled the DBX debug format instead of the UNIX/32V SDB format that GDB does not understand. But I did not need to make that big changes to Mikhail’s patch.
It is amazing how well things work – the modern assembler, linker, and debugger handles the code generated by GCC 1.27 without any problems. And command options such as
-O
, -E
, -S
, -c
, -g
, -W
, -pedantic
, and -fomit-frame-pointer
does what you expect from using a modern GCC. All the options are documented in the manual page – you can format the text by passing the gcc.1
file to man
asman -l gcc.1
How to build GCC 1.27 on Ubuntu
I have built the compiler on 64-bit Ubuntu Desktop 16.04 as described below.
Prerequisites
GCC 1.27 is a 32-bit program, so we need to install 32-bit compiler and runtime support
sudo apt install gcc-multilib
Downloading and preparing the source code
Download the source code and the patch, and apply the patch as
wget https://gcc.gnu.org/pub/gcc/old-releases/gcc-1/gcc-1.27.tar.bz2 wget https://gist.github.com/kristerw/b854b6d285e678452a44a6bcbf7ef86f/raw/gcc-1.27.patch tar xf gcc-1.27.tar.bz2 cd gcc-1.27 patch -p1 < ../gcc-1.27.patch
Configuring the source code
The compiler is configured by setting up symbolic links to the correct configuration files
ln -s config-i386v.h config.h ln -s tm-i386v.h tm.h ln -s i386.md md ln -s output-i386.c aux-output.cYou may want to change where the compiler is installed by updating
bindir
and libdir
in the Makefile
. I set them tobindir = /home/kristerw/compilers/gcc-1.27/bin libdir = /home/kristerw/compilers/gcc-1.27/lib
Build and install
The compiler is built in two (or three) stages, We start by building it using the system compiler
makeWe then build it again using the newly built compiler
make stage1 make CC=stage1/gcc CFLAGS="-O -Bstage1/ -Iinclude"As a third, optional, step, we build it again using the second compiler and checks that the resulting binaries are identical with the second compiler (if not, then the compiler has miscompiled itself).
make stage2 make CC=stage2/gcc CFLAGS="-O -Bstage2/ -Iinclude" diff cpp stage2/cpp diff gcc stage2/gcc diff cc1 stage2/cc1We are now ready to install the compiler
make install
I've been using gcc 1.27 to build doom of all thing. I had to use the ASM version for the fixed math, as there is no long long type.
ReplyDeleteAnyways, I've been wondering how hard it would be to convert gcc 1.27 to compile to 32bit instructions & registers in long mode for a "64 bit" version.. although it'd require thunking to interface with any libraries....