From 905e5880717816e276bdeacd9e158dfcea696731 Mon Sep 17 00:00:00 2001 From: d00f <8052722+DrDoof@users.noreply.github.com> Date: Tue, 20 Oct 2026 14:53:33 +0200 Subject: [PATCH] build: build SDCC 4.6.0 with two mcs51 fixes in the tree Released SDCC 4.5.0 and 4.6.0 miscompile some of our code in the mcs51 register allocator (SDCC bugs 4153 and 4154, fixed in trunk r17025 and r17039). The first make now downloads the 4.6.0 sources, checks their sha256, applies the two fixes from sdcc/ and installs the compiler into toolchain/, named after a checksum of sdcc/, so a changed patch builds a new one. make CC=sdcc still uses an installed compiler. --- .dockerignore | 1 + .gitignore | 1 + Makefile | 15 ++++++++++++--- README.md | 11 ++++++++--- sdcc/0001-mcs51-positionRegs.patch | 15 +++++++++++++++ sdcc/0002-mcs51-spillThis.patch | 24 ++++++++++++++++++++++++ sdcc/build.sh | 26 ++++++++++++++++++++++++++ 7 files changed, 87 insertions(+), 6 deletions(-) create mode 100644 sdcc/0001-mcs51-positionRegs.patch create mode 100644 sdcc/0002-mcs51-spillThis.patch create mode 100755 sdcc/build.sh 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