diff --git a/.dockerignore b/.dockerignore index f3bb7aeb..fb0cbbbf 100644 --- a/.dockerignore +++ b/.dockerignore @@ -3,6 +3,7 @@ .gitattributes .github/ output/ +toolchain/ installer/output/ *.bin html_data.c diff --git a/.gitignore b/.gitignore index 9f544835..e3793b25 100644 --- a/.gitignore +++ b/.gitignore @@ -2,6 +2,7 @@ .idea/ output/ output-main/ +toolchain/ html_data.c html_data.h version.h diff --git a/Makefile b/Makefile index 5754ee08..90fbcebf 100644 --- a/Makefile +++ b/Makefile @@ -4,8 +4,11 @@ DEFAULT_CONFIG_LOCATION = 454656 CONFIG_LOCATION = 458752 HTML_LOCATION = 262144 +SDCC_PREFIX = toolchain/sdcc-$(shell cat sdcc/* | cksum | cut -d' ' -f1) ifeq ($(origin CC),default) -CC = sdcc +SDCC = $(SDCC_PREFIX)/bin/sdcc +CC = $(SDCC) +ASM = $(SDCC_PREFIX)/bin/sdas8051 endif CC_FLAGS = -mmcs51 -I. -Imachine -Ihttpd -Iuip ASM ?= sdas8051 @@ -72,7 +75,7 @@ all: create_build_dir $(VERSION_HEADER) $(MACHINE_SRC) $(SUBDIRS) $(BUILDDIR)/rt bank_size: tools/bank_occupancy.sh "$(MACHINE)" -create_build_dir: +create_build_dir: $(SDCC) mkdir -p "$(BUILDDIR)" mkdir -p "$(BUILDDIR)/uip" mkdir -p "$(BUILDDIR)/httpd" @@ -175,6 +178,12 @@ clean: $(SUBDIRSCLEAN) distclean: $(SUBDIRSCLEAN) -rm -f html_data.c html_data.h $(VERSION_HEADER) -rm -rf $(BUILDDIR) + -rm -rf toolchain + +ifneq ($(SDCC),) +$(SDCC): + sh sdcc/build.sh $(abspath $(SDCC_PREFIX)) +endif $(SUBDIRSCLEAN): $(MAKE) -C $(@:clean=) clean @@ -223,7 +232,7 @@ MACHINE_DEFS := $(sort $(patsubst machine/%.c,%,$(filter-out machine/%_init.c,$( MACHINE_LESS_CC_FLAGS = $(filter-out -DMACHINE_%,$(CC_FLAGS)) .PHONY: machine_check -machine_check: +machine_check: $(SDCC) @mkdir -p $(BUILDDIR)/tmp @set -eo pipefail; \ for MACHINE in $(MACHINE_DEFS); \ diff --git a/README.md b/README.md index 22d9df5d..d7d664d4 100644 --- a/README.md +++ b/README.md @@ -56,12 +56,17 @@ device simulator is provided, which runs entirely under Linux as a local webserv ## (0) Compiling Requirements -Install the following particular build requisites (Debian 12/13), note that Ubuntu 24.04 -still has an older version of sdcc, but you will need sdcc version 4.5 for the code to compile: +Install the following particular build requisites (Debian 12/13): ``` -sudo apt install make gcc sdcc xxd python-is-python3 libjson-c-dev zlib1g-dev +sudo apt install make gcc g++ bison flex libboost-dev patch bzip2 curl xxd python-is-python3 libjson-c-dev zlib1g-dev ``` +The first `make` downloads SDCC 4.6.0, applies the fixes in `sdcc/` and builds it into +`toolchain/`, which takes a few minutes. Later builds reuse it. The released SDCC 4.5.0 +and 4.6.0 miscompile parts of this code, see [SDCC bug #4153](https://sourceforge.net/p/sdcc/bugs/4153/) +and [#4154](https://sourceforge.net/p/sdcc/bugs/4154/); both fixes are in SDCC trunk since +r17039. To use an SDCC you installed yourself instead, run `make CC=sdcc ...`. +
If using Docker (click to expand) diff --git a/sdcc/0001-mcs51-positionRegs.patch b/sdcc/0001-mcs51-positionRegs.patch new file mode 100644 index 00000000..e71fda96 --- /dev/null +++ b/sdcc/0001-mcs51-positionRegs.patch @@ -0,0 +1,15 @@ +https://sourceforge.net/p/sdcc/bugs/4153/ + +Index: src/mcs51/ralloc.c +=================================================================== +--- src/mcs51/ralloc.c (revision 17011) ++++ src/mcs51/ralloc.c (working copy) +@@ -1208,7 +1208,7 @@ + int change = 0; + + /* if the result has been spilt then cannot share */ +- if (opsym->isspilt) ++ if (result->isspilt || opsym->isspilt) + return 0; + + for (;;) diff --git a/sdcc/0002-mcs51-spillThis.patch b/sdcc/0002-mcs51-spillThis.patch new file mode 100644 index 00000000..0f9c8d40 --- /dev/null +++ b/sdcc/0002-mcs51-spillThis.patch @@ -0,0 +1,24 @@ +https://sourceforge.net/p/sdcc/bugs/4154/ + +Index: src/mcs51/ralloc.c +=================================================================== +--- src/mcs51/ralloc.c (revision 17011) ++++ src/mcs51/ralloc.c (working copy) +@@ -641,6 +641,7 @@ + spillThis (symbol * sym) + { + int i; ++ bool ownsRegs = bitVectBitValue (_G.regAssigned, sym->key); + /* if this is rematerializable or has a spillLocation + we are okay, else we need to create a spillLocation + for it */ +@@ -658,7 +659,8 @@ + { + if (sym->regs[i]) + { +- freeReg (sym->regs[i]); ++ if (ownsRegs) ++ freeReg (sym->regs[i]); + sym->regs[i] = NULL; + } + } diff --git a/sdcc/build.sh b/sdcc/build.sh new file mode 100755 index 00000000..a312316e --- /dev/null +++ b/sdcc/build.sh @@ -0,0 +1,26 @@ +#!/bin/sh +set -eu +V=4.6.0 +SHA=5fd6a93e5997ce01756868fe35e441095cfb637894a80c262514a634094973b6 +PREFIX=$1 +D=$(cd "$(dirname "$0")" && pwd) +W=$(mktemp -d) +trap 'rm -rf "$W"' EXIT +curl -fL -o "$W/sdcc.tar.bz2" "https://downloads.sourceforge.net/project/sdcc/sdcc/$V/sdcc-src-$V.tar.bz2" +if command -v sha256sum >/dev/null; then + echo "$SHA $W/sdcc.tar.bz2" | sha256sum -c - +else + echo "$SHA $W/sdcc.tar.bz2" | shasum -a 256 -c - +fi +tar -C "$W" -xjf "$W/sdcc.tar.bz2" +cd "$W/sdcc-$V" +for p in "$D"/*.patch; do + patch -p0 < "$p" +done +off="" +for p in z80 z180 r2k r2ka r3ka r4k r5k r6k sm83 tlcs90 ez80 ez80_z80 z80n r800 ds390 ds400 pic14 pic16 hc08 s08 stm8 pdk13 pdk14 pdk15 mos6502 mos65c02 huc6280 f8 f8l; do + off="$off --disable-$p-port" +done +./configure --prefix="$PREFIX" $off --disable-sdcdb --disable-ucsim --disable-non-free +make -j"$(getconf _NPROCESSORS_ONLN)" +make install