Add Pentium 4 Linux support

This commit is contained in:
2026-07-17 19:43:26 -05:00
parent 7f33d448c7
commit 136b417cf8
5 changed files with 76 additions and 7 deletions
+10
View File
@@ -34,6 +34,10 @@ jobs:
os: ubuntu-24.04 os: ubuntu-24.04
openssl_target: linux-x86_64 openssl_target: linux-x86_64
cross_prefix: '' cross_prefix: ''
- target: linux-i386
os: ubuntu-24.04
openssl_target: linux-x86
cross_prefix: ''
- target: linux-arm64 - target: linux-arm64
os: ubuntu-24.04 os: ubuntu-24.04
openssl_target: linux-aarch64 openssl_target: linux-aarch64
@@ -61,6 +65,12 @@ jobs:
sudo apt-get update sudo apt-get update
sudo apt-get install --yes gcc-aarch64-linux-gnu sudo apt-get install --yes gcc-aarch64-linux-gnu
- name: Install the Linux i386 multilib compiler
if: matrix.target == 'linux-i386'
run: |
sudo apt-get update
sudo apt-get install --yes gcc-multilib
- name: Install the Linux PPC32 big-endian cross-compiler - name: Install the Linux PPC32 big-endian cross-compiler
if: matrix.target == 'linux-ppc32be' if: matrix.target == 'linux-ppc32be'
run: | run: |
+23 -3
View File
@@ -48,6 +48,7 @@ DIST := dist
DRIVER := src/main.c DRIVER := src/main.c
ASM_ARM64 := src/fossmark.S ASM_ARM64 := src/fossmark.S
ASM_AMD64 := src/fossmark_x86_64.S ASM_AMD64 := src/fossmark_x86_64.S
SRC_I386 := src/fossmark_ppc32.c
SRC_PPC32 := src/fossmark_ppc32.c SRC_PPC32 := src/fossmark_ppc32.c
ASM_PPC32 := src/fossmark_ppc32_ext.S ASM_PPC32 := src/fossmark_ppc32_ext.S
SRC_PPC64 := src/fossmark_ppc32.c SRC_PPC64 := src/fossmark_ppc32.c
@@ -60,6 +61,9 @@ ifneq (,$(filter aarch64 arm64,$(HOST_ARCH)))
else ifneq (,$(filter x86_64 amd64,$(HOST_ARCH))) else ifneq (,$(filter x86_64 amd64,$(HOST_ARCH)))
HOST_ARCHNAME := amd64 HOST_ARCHNAME := amd64
HOST_KERNEL := $(ASM_AMD64) HOST_KERNEL := $(ASM_AMD64)
else ifneq (,$(filter i386 i486 i586 i686 x86,$(HOST_ARCH)))
HOST_ARCHNAME := i386
HOST_KERNEL := $(SRC_I386)
else ifneq (,$(filter ppc powerpc ppc32 powerpc32,$(HOST_ARCH))) else ifneq (,$(filter ppc powerpc ppc32 powerpc32,$(HOST_ARCH)))
HOST_ARCHNAME := ppc32be HOST_ARCHNAME := ppc32be
HOST_KERNEL := $(SRC_PPC32) $(ASM_PPC32) HOST_KERNEL := $(SRC_PPC32) $(ASM_PPC32)
@@ -68,7 +72,10 @@ else ifneq (,$(filter ppc64 powerpc64,$(HOST_ARCH)))
HOST_KERNEL := $(SRC_PPC64) HOST_KERNEL := $(SRC_PPC64)
else else
HOST_ARCHNAME := $(HOST_ARCH) HOST_ARCHNAME := $(HOST_ARCH)
$(error unsupported host architecture '$(HOST_ARCH)') $(error unsupported host architecture '$(HOST_ARCH)')
endif
ifeq ($(HOST_ARCHNAME),i386)
CFLAGS += -march=pentium4 -msse2
endif endif
ifeq ($(HOST_ARCHNAME),ppc64be) ifeq ($(HOST_ARCHNAME),ppc64be)
CFLAGS += -mcpu=970 -maltivec CFLAGS += -mcpu=970 -maltivec
@@ -100,6 +107,11 @@ ifeq ($(HOST_ARCHNAME),amd64)
else else
CC_AMD64 ?= x86_64-linux-gnu-gcc CC_AMD64 ?= x86_64-linux-gnu-gcc
endif endif
ifeq ($(HOST_ARCHNAME),i386)
CC_I386 ?= $(CC)
else
CC_I386 ?= cc
endif
CC_MACOS_ARM64 ?= $(CC) CC_MACOS_ARM64 ?= $(CC)
CC_MACOS_AMD64 ?= $(CC) CC_MACOS_AMD64 ?= $(CC)
MACOS_AMD64_MIN ?= 10.5 MACOS_AMD64_MIN ?= 10.5
@@ -118,16 +130,17 @@ NATIVE_BIN := $(DIST)/fossmark-$(OSNAME)-$(HOST_ARCHNAME)
# `make` with no target builds the host binary, as before. # `make` with no target builds the host binary, as before.
.DEFAULT_GOAL := native .DEFAULT_GOAL := native
.PHONY: all native linux-arm64 linux-amd64 linux-ppc32be linux-ppc64be macos-arm64 macos-amd64 bench test clean .PHONY: all native linux-arm64 linux-amd64 linux-i386 linux-ppc32be linux-ppc64be macos-arm64 macos-amd64 bench test clean
# `make all` builds all Linux binaries. # `make all` builds all Linux binaries.
all: linux-arm64 linux-amd64 linux-ppc32be linux-ppc64be all: linux-arm64 linux-amd64 linux-i386 linux-ppc32be linux-ppc64be
# `make native` (and bare `make`) build for whatever host you are on. # `make native` (and bare `make`) build for whatever host you are on.
native: $(NATIVE_BIN) native: $(NATIVE_BIN)
linux-arm64: $(DIST)/fossmark-linux-arm64 linux-arm64: $(DIST)/fossmark-linux-arm64
linux-amd64: $(DIST)/fossmark-linux-amd64 linux-amd64: $(DIST)/fossmark-linux-amd64
linux-i386: $(DIST)/fossmark-linux-i386
linux-ppc32be: $(DIST)/fossmark-linux-ppc32be linux-ppc32be: $(DIST)/fossmark-linux-ppc32be
linux-ppc64be: $(DIST)/fossmark-linux-ppc64be linux-ppc64be: $(DIST)/fossmark-linux-ppc64be
macos-arm64: $(DIST)/fossmark-macos-arm64 macos-arm64: $(DIST)/fossmark-macos-arm64
@@ -141,6 +154,10 @@ $(DIST)/fossmark-linux-amd64: $(DRIVER) $(ASM_AMD64) | $(DIST)
$(CC_AMD64) $(CFLAGS) $(TLS_CFLAGS) $(PTHREAD) $(LDFLAGS) -o $@ $(DRIVER) $(ASM_AMD64) $(LDLIBS) $(CC_AMD64) $(CFLAGS) $(TLS_CFLAGS) $(PTHREAD) $(LDFLAGS) -o $@ $(DRIVER) $(ASM_AMD64) $(LDLIBS)
@echo "built $@" @echo "built $@"
$(DIST)/fossmark-linux-i386: $(DRIVER) $(SRC_I386) | $(DIST)
$(CC_I386) -m32 -march=pentium4 -msse2 $(CFLAGS) $(TLS_CFLAGS) $(PTHREAD) $(LDFLAGS) -o $@ $(DRIVER) $(SRC_I386) $(LDLIBS)
@echo "built $@"
$(DIST)/fossmark-linux-ppc32be: $(DRIVER) $(SRC_PPC32) $(ASM_PPC32) | $(DIST) $(DIST)/fossmark-linux-ppc32be: $(DRIVER) $(SRC_PPC32) $(ASM_PPC32) | $(DIST)
$(CC_PPC32BE) $(CFLAGS) $(TLS_CFLAGS) $(PTHREAD) $(LDFLAGS) -o $@ $(DRIVER) $(SRC_PPC32) $(ASM_PPC32) $(LDLIBS) $(CC_PPC32BE) $(CFLAGS) $(TLS_CFLAGS) $(PTHREAD) $(LDFLAGS) -o $@ $(DRIVER) $(SRC_PPC32) $(ASM_PPC32) $(LDLIBS)
@echo "built $@" @echo "built $@"
@@ -166,6 +183,9 @@ endif
ifeq ($(OSNAME)-$(HOST_ARCHNAME),linux-amd64) ifeq ($(OSNAME)-$(HOST_ARCHNAME),linux-amd64)
NATIVE_HAS_RULE := yes NATIVE_HAS_RULE := yes
endif endif
ifeq ($(OSNAME)-$(HOST_ARCHNAME),linux-i386)
NATIVE_HAS_RULE := yes
endif
ifeq ($(OSNAME)-$(HOST_ARCHNAME),linux-ppc32be) ifeq ($(OSNAME)-$(HOST_ARCHNAME),linux-ppc32be)
NATIVE_HAS_RULE := yes NATIVE_HAS_RULE := yes
endif endif
+3 -1
View File
@@ -6,7 +6,7 @@ across every available core. The final report includes separate single-core and
multicore scores. multicore scores.
The repository currently builds an executable named `fossmark` for ARM64, The repository currently builds an executable named `fossmark` for ARM64,
x86-64, and 32- or 64-bit big-endian PowerPC. The C driver handles timing, memory, x86 (Pentium 4 or newer), x86-64, and 32- or 64-bit big-endian PowerPC. The C driver handles timing, memory,
threads, output, and scoring. Performance-sensitive kernels live in threads, output, and scoring. Performance-sensitive kernels live in
architecture-specific backend files. architecture-specific backend files.
@@ -50,6 +50,7 @@ Other targets are available for explicit platforms and architectures:
```sh ```sh
make linux-arm64 make linux-arm64
make linux-amd64 make linux-amd64
make linux-i386 # Pentium 4 / SSE2 baseline
make linux-ppc32be make linux-ppc32be
make linux-ppc64be # PowerPC 970 / iMac G5 make linux-ppc64be # PowerPC 970 / iMac G5
make macos-arm64 make macos-arm64
@@ -63,6 +64,7 @@ toolchain. Override the target compiler when its name differs from the default:
```sh ```sh
make linux-arm64 CC_ARM64=aarch64-linux-gnu-gcc make linux-arm64 CC_ARM64=aarch64-linux-gnu-gcc
make linux-amd64 CC_AMD64=x86_64-linux-gnu-gcc make linux-amd64 CC_AMD64=x86_64-linux-gnu-gcc
make linux-i386 CC_I386=gcc
make linux-ppc32be CC_PPC32BE=powerpc-linux-gnu-gcc make linux-ppc32be CC_PPC32BE=powerpc-linux-gnu-gcc
make linux-ppc64be CC_PPC64BE=powerpc64-linux-gnu-gcc make linux-ppc64be CC_PPC64BE=powerpc64-linux-gnu-gcc
``` ```
+31 -2
View File
@@ -11,6 +11,10 @@
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#if defined(__i386__) || defined(__x86_64__) || defined(_M_IX86) || defined(_M_X64)
#include <emmintrin.h>
#endif
#if defined(__linux__) #if defined(__linux__)
#include <sys/auxv.h> #include <sys/auxv.h>
#endif #endif
@@ -64,7 +68,7 @@ uint64_t fm_primes(uint64_t limit, uint8_t *sieve)
return count; return count;
} }
#if !defined(__powerpc64__) #if defined(__powerpc__) && !defined(__powerpc64__)
static uint64_t fm_simd_scalar(uint64_t iters, void *memory) static uint64_t fm_simd_scalar(uint64_t iters, void *memory)
{ {
uint32_t *v = (uint32_t *)memory; uint32_t *v = (uint32_t *)memory;
@@ -109,7 +113,7 @@ uint64_t fm_simd(uint64_t iters, void *memory)
sum ^= v[j]; sum ^= v[j];
return sum; return sum;
} }
#else #elif defined(__powerpc__)
/* These are kept in fossmark_ppc32_ext.S so this translation unit, and thus /* These are kept in fossmark_ppc32_ext.S so this translation unit, and thus
* the executable's default code path, only requires baseline PPC32. */ * the executable's default code path, only requires baseline PPC32. */
extern void fm_simd_ps_kernel(uint64_t iters, void *memory); extern void fm_simd_ps_kernel(uint64_t iters, void *memory);
@@ -192,6 +196,31 @@ uint64_t fm_simd(uint64_t iters, void *memory)
sum ^= v[j]; sum ^= v[j];
return sum; return sum;
} }
#else
uint64_t fm_simd(uint64_t iters, void *memory)
{
__m128i a, b;
uint32_t *v = (uint32_t *)memory;
uint32_t sum = 0;
uint64_t i;
unsigned j;
if (!iters)
return 0;
a = _mm_loadu_si128((const __m128i *)v);
b = _mm_loadu_si128((const __m128i *)(v + 4));
for (i = 0; i < iters; i++) {
a = _mm_add_epi32(a, b);
b = _mm_xor_si128(b, a);
a = _mm_add_epi32(a, b);
b = _mm_xor_si128(b, a);
}
_mm_storeu_si128((__m128i *)v, a);
_mm_storeu_si128((__m128i *)(v + 4), b);
for (j = 0; j < 8; j++)
sum ^= v[j];
return sum;
}
#endif #endif
static uint32_t load32_native(const uint8_t *p) static uint32_t load32_native(const uint8_t *p)
+9 -1
View File
@@ -42,7 +42,7 @@
#ifndef FM_API_BASE_URL #ifndef FM_API_BASE_URL
# define FM_API_BASE_URL "https://fossbench.net" # define FM_API_BASE_URL "https://fossbench.net"
#endif #endif
#define FM_VERSION "0.1.3-hotfix3" #define FM_VERSION "0.1.3-hotfix4"
/* ---------- platform identification (for the banner only) ---------- */ /* ---------- platform identification (for the banner only) ---------- */
@@ -66,6 +66,11 @@
# define D_INT "64-bit ALU: imul, mul, div, bitops" # define D_INT "64-bit ALU: imul, mul, div, bitops"
# define D_FP "double: mulsd/addsd, divsd, sqrtsd" # define D_FP "double: mulsd/addsd, divsd, sqrtsd"
# define D_SIMD "SSE2: 128-bit integer + float" # define D_SIMD "SSE2: 128-bit integer + float"
#elif defined(__i386__) || defined(_M_IX86)
# define FM_ARCH "x86 32-bit"
# define D_INT "Pentium 4 integer ALU and software 64-bit arithmetic"
# define D_FP "x87 scalar double-precision floating point"
# define D_SIMD "SSE2: 128-bit integer vectors"
#elif defined(__powerpc64__) #elif defined(__powerpc64__)
# define FM_ARCH "PowerPC 64-bit big-endian" # define FM_ARCH "PowerPC 64-bit big-endian"
# define D_INT "64-bit PowerPC integer ALU" # define D_INT "64-bit PowerPC integer ALU"
@@ -145,6 +150,9 @@ extern uint64_t fm_chase(void **ptrs, uint64_t steps);
#if defined(__powerpc__) && !defined(__powerpc64__) #if defined(__powerpc__) && !defined(__powerpc64__)
# define CHASE_NODES (1u << 19) /* 2 MiB with 32-bit pointers */ # define CHASE_NODES (1u << 19) /* 2 MiB with 32-bit pointers */
# define CHASE_DETAIL "dependent-load pointer chase, 2 MiB" # define CHASE_DETAIL "dependent-load pointer chase, 2 MiB"
#elif UINTPTR_MAX == UINT32_MAX
# define CHASE_NODES (1u << 21) /* 8 MiB with 32-bit pointers */
# define CHASE_DETAIL "dependent-load pointer chase, 8 MiB"
#else #else
# define CHASE_NODES (1u << 21) /* 16 MiB cycle, > any L2 */ # define CHASE_NODES (1u << 21) /* 16 MiB cycle, > any L2 */
# define CHASE_DETAIL "dependent-load pointer chase, 16 MiB" # define CHASE_DETAIL "dependent-load pointer chase, 16 MiB"