summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Makefile61
-rw-r--r--README21
-rwxr-xr-xexpand-translations29
-rw-r--r--isa-list351
-rwxr-xr-xqemu-@QEMUTYPE@-@NAME@10
-rwxr-xr-xrefresh-package210
-rw-r--r--test-@NAME@.c75
7 files changed, 757 insertions, 0 deletions
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..5a7859a
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,61 @@
+DEB_HOST_MULTIARCH ?= $(shell dpkg-architecture -qDEB_HOST_MULTIARCH)
+DEB_HOST_ARCH ?= $(shell dpkg-architecture -qDEB_HOST_ARCH)
+prefix?=/usr
+exec_prefix?=$(prefix)
+DESTDIR?=
+libexecdir?=$(exec_prefix)/libexec
+archlibexecdir?=$(exec_prefix)/libexec/$(DEB_HOST_MULTIARCH)
+INSTALL?=install
+
+uniq = $(if $1,$(firstword $1) $(call uniq,$(filter-out $(firstword $1),$1)))
+
+ISAS_ARCH_LIST:=$(shell cat isa-list | grep '^Architecture:' | cut -d ':' -f2 | sort -u)
+ISAS_ARCH_FORUS:=$(call uniq, $(foreach isaarch, $(ISAS_ARCH_LIST), $(shell dpkg-architecture -a $(DEB_HOST_ARCH) -i $(isaarch) && echo $(isaarch))))
+ISAS_ARCH_FORUS_GREP:=$(foreach isa, $(ISAS_ARCH_FORUS), -e '^Architecture:.*[[:space:]]$(isa)')
+
+ISAS:= $(shell cat isa-list | grep -A1 ^Name | grep -B1 $(ISAS_ARCH_FORUS_GREP) -e 'FakeArchIsEmptySet' | grep ^Name | cut -d ' ' -f2)
+
+
+
+TEST_BINARIES = $(foreach isa,$(ISAS),test-$(isa))
+QEMU_BINARIES = $(foreach type,good static-good bad static-bad,$(foreach isa,$(ISAS),qemu-$(type)-$(isa)))
+TEST_SOURCES = $(foreach isa,$(ISAS),test-$(isa).c)
+
+GENERATED_FILES += $(foreach isa,$(ISAS),debian/$(isa).docs)
+GENERATED_FILES += $(foreach isa,$(ISAS),debian/$(isa).lintian-overrides)
+GENERATED_FILES += $(foreach isa,$(ISAS),debian/$(isa).preinst)
+GENERATED_FILES += $(foreach isa,$(ISAS),debian/$(isa).templates)
+GENERATED_FILES += $(TEST_SOURCES)
+ALL_GENERATED_FILES += $(GENERATED_FILES) debian/control
+ALL_BINARIES = $(TEST_BINARIES) $(QEMU_BINARIES)
+
+INPUT_FILES = $(wildcard debian/*.in)
+
+CFLAGS ?=
+CFLAGS += -Wall
+CFLAGS += $(shell cat isa-list | sed -e 's/^Name: /Name: test-/' | grep $@ -A3 | grep '^CFLAGS:' | cut -d ' ' -f2-)
+
+all: $(TEST_BINARIES)
+ @:
+
+clean:
+ rm -f $(GENERATED_FILES)
+ rm -f $(ALL_BINARIES)
+ rm -f .last-refresh
+
+install:
+ mkdir -p $(DESTDIR)/$(archlibexecdir)/isa-support
+ for bin in $(TEST_BINARIES); do $(INSTALL) $$bin $(DESTDIR)/$(archlibexecdir)/isa-support; done
+ for bin in $(QEMU_BINARIES); do if test -e $$bin; then $(INSTALL) $$bin $(DESTDIR)/$(archlibexecdir)/isa-support; fi; done
+
+refresh: $(ALL_GENERATED_FILES) $(TEST_SOURCES)
+ @:
+
+$(GENERATED_FILES): .last-refresh
+ @:
+
+.last-refresh: refresh-package $(INPUT_FILES)
+ ./refresh-package
+ touch $@
+
+.PHONY: all clean refresh
diff --git a/README b/README
new file mode 100644
index 0000000..629a1bb
--- /dev/null
+++ b/README
@@ -0,0 +1,21 @@
+This package ensures that the machine has required CPU facilities; users who
+attempt installation on an inadequate processor will receive an error message
+in preinst. This is useful if there's no way to make your package support
+the base ISA for the architecture.
+
+While in general packages are required to at least try, there are situations
+when baseline support is infeasible or a pure waste of time. No one is
+going to run scientific number-crunching software on a pre-SSE2/SSE3
+machine. Or upstream code may use such extensions unconditionally, and
+you don't have the resources to fix that yourself.
+
+You should also consider how likely other software is to use your package.
+A fast strong hash is something with many uses, big and small, so it's a
+priority to port libraries like libhighwayhash to all CPUs. On the other
+hand, a niche piece of software is unlikely to be repurposed for other uses.
+
+
+The check is skipped in two cases:
+* when the target architecture is not executable at all (an ARM SoC mounted
+ into an amd64 machine, etc)
+* when ISA_IGNORE environment variable has a non-empty value
diff --git a/expand-translations b/expand-translations
new file mode 100755
index 0000000..0683507
--- /dev/null
+++ b/expand-translations
@@ -0,0 +1,29 @@
+#!/bin/sh
+
+set -eu
+
+outdir="$1"
+
+mkdir -p "$outdir"
+
+isas=$(cat isa-list | grep ^Name | cut -d " " -f2)
+
+for po in debian/po/*.po ; do
+ po2="$outdir/$(basename "$po")"
+ truncate -s0 "$po2"
+
+ echo "Extending $po: s/&NAME&/\$isa > $po2"
+ csplit --quiet --suppress-matched -f "$po2." -b '%02d.sect' "$po" '/^$/' '{*}'
+ for sect in $(ls -1 $po2*.sect | sort -n) ; do
+ if grep -q '@NAME@' $sect ; then
+ for isa in $isas ; do
+ cat $sect | sed -e "s/@NAME@/$isa/g" >> "$po2"
+ echo >> "$po2"
+ done
+ else
+ cat $sect >> "$po2"
+ echo >> "$po2"
+ fi
+ rm $sect
+ done
+done
diff --git a/isa-list b/isa-list
new file mode 100644
index 0000000..07222de
--- /dev/null
+++ b/isa-list
@@ -0,0 +1,351 @@
+# Recognized fields:
+# "Name": the isa extension name, the package will be ${Name}-support
+# "Architecture": archs to build the package on, wildcards are ok
+# "Test": how to detect it, defaults to return !__builtin_cpu_supports("$Name");
+# If the test program dies (SIGILL/etc), that's ok, the answer is "no".
+# CFLAGS: passed to the C compiler, can include link-time flags too.
+# Description: added to package's description.
+# qemu-good: qemu run ok
+# qemu-bad: qemu not ok
+# package: yes/no add a package for this test. Default no
+# priority: higher are tested first
+
+Name: i386-baseline
+Architecture: any-i386
+Package: no
+Priority: -1
+Test: return !(
+ __builtin_cpu_supports("cmov") &&
+ CPU_FEATURE_ACTIVE(CX8)
+ );
+qemu-good: "qemu-$DEB_HOST_MULTIARCH_CPU""$QEMU_EXTRA" -cpu pentium',+cmov,+cx8'
+qemu-bad: "qemu-$DEB_HOST_MULTIARCH_CPU""$QEMU_EXTRA" -cpu pentium',-cmov,-cx8'
+Description:
+ This is the Micro-Architecture Levels baseline for debian under i386 architecture, corresponding
+ to i686 CPU.
+ .
+ This includes:
+ - cmov instruction (CMOV instruction set),
+ - cmpxchg8b ant other 64 bits atomics instruction (CX8 instruction set).
+
+Name: SSE2
+Architecture: any-i386
+qemu-good: "qemu-$DEB_HOST_MULTIARCH_CPU""$QEMU_EXTRA" -cpu qemu"$DEB_HOST_ARCH_BITS"',+sse2'
+qemu-bad: "qemu-$DEB_HOST_MULTIARCH_CPU""$QEMU_EXTRA" -cpu qemu"$DEB_HOST_ARCH_BITS"',-sse2,-sse3,-ssse3,-sse4.1,-sse4.2'
+Priority: 500
+Package: yes
+Description:
+ Streaming SIMD Extensions (SSE) is a single instruction, multiple data
+ (SIMD) instruction set extension.
+ .
+ SSE2 was an incremental upgrade to SSE intended to fully replace the earlier
+ MMX instruction set. It is available on processors from Pentium 4 onward,
+ including all 64-bit capable ones, but not on Pentium 3, Athlon XP, Via C3,
+ Quark, or older processors.
+
+Name: amd64-baseline
+Architecture: any-i386 any-amd64
+Package: no
+Priority: -1
+Test: return !(
+ __builtin_cpu_supports("cmov") && __builtin_cpu_supports("mmx") && __builtin_cpu_supports("sse") &&
+ __builtin_cpu_supports("sse2") &&
+ CPU_FEATURE_ACTIVE(CX8) && CPU_FEATURE_ACTIVE(FXSR)
+ );
+qemu-good: "qemu-$DEB_HOST_MULTIARCH_CPU""$QEMU_EXTRA" -cpu qemu"$DEB_HOST_ARCH_BITS"',+cmov,+mmx,+sse,+sse2,+cx8,+fxsr'
+qemu-bad: "qemu-$DEB_HOST_MULTIARCH_CPU""$QEMU_EXTRA" -cpu qemu"$DEB_HOST_ARCH_BITS"',-sse,-sse2'
+Description:
+ This is the Micro-Architecture Levels baseline for debian under x86-64 architecture, corresponding
+ to x86-65 psABI v1.
+ .
+ This includes:
+ - cmov instruction (CMOV instruction set),
+ - cmpxchg8b ant other 64 bits atomics instruction (CX8 instruction set),
+ - MMX a single instruction, multiple data (SIMD) instruction set,
+ - streaming SIMD Extensions (SSE) set, a single instruction, multiple data
+ (SIMD) instruction set extension,
+ - SSE2 an incremental upgrade to SSE.
+ .
+ On ABIs other than the x86-64 psABI they select the same CPU features
+ as the x86-64 psABI documents for the particular micro-architecture level.
+
+Name: x86-64-v1
+Architecture: any-i386
+Package: no
+Priority: 1000
+Test: return !(
+ __builtin_cpu_supports("cmov") && __builtin_cpu_supports("mmx") && __builtin_cpu_supports("sse") &&
+ __builtin_cpu_supports("sse2") &&
+ CPU_FEATURE_ACTIVE(CX8) && CPU_FEATURE_ACTIVE(FXSR)
+ );
+qemu-good: "qemu-$DEB_HOST_MULTIARCH_CPU""$QEMU_EXTRA" -cpu qemu"$DEB_HOST_ARCH_BITS"',+cmov,+mmx,+sse,+sse2,+cx8,+fxsr'
+qemu-bad: "qemu-$DEB_HOST_MULTIARCH_CPU""$QEMU_EXTRA" -cpu qemu"$DEB_HOST_ARCH_BITS"',-cmov,-mmx,-sse,-sse2,-cx8,-fxsr'
+Description:
+ This is the Micro-Architecture Levels baseline as defined by the amd64 ABI document.
+ This includes:
+ - cmov instruction (CMOV instruction set),
+ - cmpxchg8b ant other 64 bits atomics instruction (CX8 instruction set),
+ - MMX a single instruction, multiple data (SIMD) instruction set,
+ - streaming SIMD Extensions (SSE) set, a single instruction, multiple data
+ (SIMD) instruction set extension,
+ - SSE2 an incremental upgrade to SSE.
+ .
+ On ABIs other than the x86-64 psABI they select the same CPU features
+ as the x86-64 psABI documents for the particular micro-architecture level.
+
+Name: x86-64-v2
+Architecture: any-i386 any-amd64
+Package: no
+qemu-good: "qemu-$DEB_HOST_MULTIARCH_CPU""$QEMU_EXTRA" -cpu qemu"$DEB_HOST_ARCH_BITS"'-v1,+cmov,+mmx,+sse,+sse2,+cx8,+fxsr,+cx16,+lahf-lm,+popcnt,+sse3,+sse4.1,+sse4.2,+ssse3'
+qemu-bad: "qemu-$DEB_HOST_MULTIARCH_CPU""$QEMU_EXTRA" -cpu qemu"$DEB_HOST_ARCH_BITS"'-v1,+cmov,+mmx,+sse,+sse2,+cx8,+fxsr,-cx16,-lahf-lm,-popcnt,-sse3,-sse4.1,-sse4.2,-ssse3'
+Priority: 2000
+Test: return !(
+ __builtin_cpu_supports("cmov") && __builtin_cpu_supports("mmx") && __builtin_cpu_supports("sse") &&
+ __builtin_cpu_supports("sse2") &&
+ CPU_FEATURE_ACTIVE(CX8) && CPU_FEATURE_ACTIVE(FXSR) &&
+ CPU_FEATURE_ACTIVE(CMPXCHG16B) && CPU_FEATURE_ACTIVE(LAHF64_SAHF64) &&
+ __builtin_cpu_supports("popcnt") && __builtin_cpu_supports("sse3") &&
+ __builtin_cpu_supports("sse4.1") && __builtin_cpu_supports("sse4.2") && __builtin_cpu_supports("ssse3")
+ );
+Description:
+ This is the Micro-Architecture Levels version 2 as defined by the amd64 ABI document.
+ This includes:
+ - cmov instruction (CMOV instruction set),
+ - cmpxchg8b ant other 64 bits atomics instruction (CX8 instruction set),
+ - MMX a single instruction, multiple data (SIMD) instruction set,
+ - streaming SIMD Extensions (SSE) set, a single instruction, multiple data
+ (SIMD) instruction set extension,
+ - SSE2 an incremental upgrade to SSE.
+ - cmpxchg16b ant other 128 bits atomics instruction (CX16 instruction set),
+ - SSE3, also called PNI (Prescott New Instructions), is an incremental upgrade
+ to SSE2
+ - SSE4.1 added a dot product instruction and additional integer instructions.
+ - SSE4.2 added string and text processing instructions that perform character
+ searches and comparison on two operands of 16 bytes at a time.
+ - SSSE3 or Supplemental Streaming SIMD Extension 3.
+ .
+ The corresponding micro-architecture level from the x86-64 psABI.
+ On ABIs other than the x86-64 psABI they select the same CPU features
+ as the x86-64 psABI documents for the particular micro-architecture level.
+
+Name: SSE3
+Architecture: any-i386 any-amd64
+qemu-good: "qemu-$DEB_HOST_MULTIARCH_CPU""$QEMU_EXTRA" -cpu qemu"$DEB_HOST_ARCH_BITS"',+sse2,+sse3,+ssse3'
+qemu-bad: "qemu-$DEB_HOST_MULTIARCH_CPU""$QEMU_EXTRA" -cpu qemu"$DEB_HOST_ARCH_BITS"',+sse2,-sse3,-ssse3,-sse4.1,-sse4.2'
+Package: yes
+Priority: 700
+Description:
+ Streaming SIMD Extensions (SSE) is a single instruction, multiple data
+ (SIMD) instruction set extension.
+ .
+ SSE3, also called PNI (Prescott New Instructions), is an incremental upgrade
+ to SSE2, adding a handful of new operations useful for processing media. It
+ is available on almost any 64-bit-capable processor except for some early
+ AMD models (Sledgehammer and Clawhammer), but is not available on most
+ 32-bit-only hardware.
+
+Name: SSE4.1
+Architecture: any-i386 any-amd64
+qemu-good: "qemu-$DEB_HOST_MULTIARCH_CPU""$QEMU_EXTRA" -cpu qemu"$DEB_HOST_ARCH_BITS"',+sse2,+sse3,+ssse3,+sse4.1'
+qemu-bad: "qemu-$DEB_HOST_MULTIARCH_CPU""$QEMU_EXTRA" -cpu qemu"$DEB_HOST_ARCH_BITS"',+sse2,+sse3,+ssse3,-sse4.1,-sse4.2'
+Package: yes
+Priority: 800
+Description:
+ Streaming SIMD Extensions (SSE) is a single instruction, multiple data
+ (SIMD) instruction set extension.
+ .
+ SSE4.1 added a dot product instruction and additional integer instructions.
+ It is available on Intel processors since Penryn (circa 2008), but notably
+ not on anything AMD until the Bulldozer (15h, in 2011) and Jaguar (16h, in
+ 2013) families.
+
+Name: SSE4.2
+Architecture: any-i386 any-amd64
+qemu-good: "qemu-$DEB_HOST_MULTIARCH_CPU""$QEMU_EXTRA" -cpu "qemu$DEB_HOST_ARCH_BITS"',+sse2,+sse3,+ssse3,+sse4.1,+sse4.2'
+qemu-bad: "qemu-$DEB_HOST_MULTIARCH_CPU""$QEMU_EXTRA" -cpu "qemu$DEB_HOST_ARCH_BITS"',+sse2,+sse3,+ssse3,+sse4.1,-sse4.2'
+Package: yes
+Priority: 900
+Description:
+ SSE4.2 added string and text processing instructions that perform character
+ searches and comparison on two operands of 16 bytes at a time. It is
+ available on Intel processors since Nehalem (circa 2008), but notably not
+ on anything AMD until the Bulldozer (15h, in 2011) and Jaguar (16h, in
+ 2013) families.
+
+Name: x86-64-v3
+Architecture: any-i386 any-amd64
+Priority: 3000
+Package: no
+#qemu-good: "qemu-$DEB_HOST_MULTIARCH_CPU""$QEMU_EXTRA" -cpu qemu"$DEB_HOST_ARCH_BITS"-v1',+cmov,+mmx,+sse,+sse2,+cx8,+fxsr,+cx16,+lahf-lm,+popcnt,+sse3,+sse4.1,+sse4.2,+ssse3,+avx,+avx2,+bmi1,+bmi2,+f16c,+fma,+abm'
+#qemu-bad: "qemu-$DEB_HOST_MULTIARCH_CPU""$QEMU_EXTRA" -cpu qemu"$DEB_HOST_ARCH_BITS"-v1',+cmov,+mmx,+sse,+sse2,+cx8,+fxsr,+cx16,+lahf-lm,+popcnt,+sse3,+sse4.1,+sse4.2,+ssse3,-avx,-avx2,-bmi1,-bmi2,-f16c,-fma,-abm'
+Test: return !(
+ __builtin_cpu_supports("cmov") && __builtin_cpu_supports("mmx") && __builtin_cpu_supports("sse") &&
+ __builtin_cpu_supports("sse2") &&
+ CPU_FEATURE_ACTIVE(CX8) && CPU_FEATURE_ACTIVE(FXSR) &&
+ CPU_FEATURE_ACTIVE(CMPXCHG16B) && CPU_FEATURE_ACTIVE(LAHF64_SAHF64) &&
+ __builtin_cpu_supports("popcnt") && __builtin_cpu_supports("sse3") &&
+ __builtin_cpu_supports("sse4.1") && __builtin_cpu_supports("sse4.2") && __builtin_cpu_supports("ssse3") &&
+ __builtin_cpu_supports("avx") && __builtin_cpu_supports("avx2") &&
+ __builtin_cpu_supports("bmi") && __builtin_cpu_supports("bmi2") &&
+ CPU_FEATURE_ACTIVE(F16C) &&
+ __builtin_cpu_supports("fma") &&
+ CPU_FEATURE_ACTIVE(LZCNT) && CPU_FEATURE_ACTIVE(OSXSAVE)
+ );
+Description:
+ This is the Micro-Architecture Levels version 3 as defined by the amd64 ABI document.
+ This includes:
+ - cmov instruction (CMOV instruction set),
+ - cmpxchg8b ant other 64 bits atomics instruction (CX8 instruction set),
+ - MMX a single instruction, multiple data (SIMD) instruction set,
+ - streaming SIMD Extensions (SSE) set, a single instruction, multiple data
+ (SIMD) instruction set extension,
+ - SSE2 an incremental upgrade to SSE.
+ - cmpxchg16b ant other 128 bits atomics instruction (CX16 instruction set),
+ - SSE3, also called PNI (Prescott New Instructions), is an incremental upgrade
+ to SSE2,
+ - SSE4.1 added a dot product instruction and additional integer instructions,
+ - SSE4.2 added string and text processing instructions that perform character
+ searches and comparison on two operands of 16 bytes at a time,
+ - SSSE3 or Supplemental Streaming SIMD Extension 3,
+ - Advanced Vector Extensions (AVX and AVX2)
+ - Bit manipulation instructions sets (BMI and BMI2),
+ - F16C instruction set converting between half-precision
+ and standard IEEE single-precision floating-point formats,
+ - LZCNT instruction, Count the Number of Leading Zero Bits,
+ - OSXSAVE, Save Processor Extended States instruction.
+ .
+ The corresponding micro-architecture level from the x86-64 psABI.
+ On ABIs other than the x86-64 psABI they select the same CPU features
+ as the x86-64 psABI documents for the particular micro-architecture level.
+
+
+Name: altivec
+Architecture: powerpc
+Test: asm volatile("vsldoi %v1,%v1,%v1,0");
+Package: yes
+Description:
+ AltiVec is a single-precision floating point and integer SIMD instruction
+ set. It is a standard part of the Power ISA v.2.03 specification.
+# gcc-16 has __builtin_cpu_supports("altivec") but it's not reliable: silently
+# gives wrong answer on qemu, wrong versions of glibc, non-glibc, etc.
+# Thus, let's use SIGILL instead.
+
+Name: neon
+Architecture: armhf
+CFLAGS: -mfpu=neon
+Test: asm volatile("VMUL.I16 q0,q0,q1");
+Package: yes
+Description:
+ This is a mostly dummy package which checks for Neon and refuses to install
+ on unsupported hardware.
+ .
+ Neon, also known as MPE (Media Processing Engine) or Advanced SIMD, is a
+ combined 64- and 128-bit SIMD instruction set that provides standardised
+ acceleration for media and signal processing applications. It is available
+ on the vast majority of armhf devices but not guaranteed before the 64-bit
+ capable ARMv8.
+
+Name: ARMv6
+Architecture: armel
+Test: return !need_armv_version(6);
+#qemu-bad: "qemu-$DEB_HOST_MULTIARCH_CPU""$QEMU_EXTRA" -cpu arm1026
+#qemu-good: "qemu-$DEB_HOST_MULTIARCH_CPU""$QEMU_EXTRA" -cpu arm1136-r2
+Package: yes
+Priority: 6000
+Description:
+ The ARMv6 architecture (not to be confused with product family ARM6) uses
+ physically addressed cache, solving many cache aliasing problems and
+ reducing context switch overhead. Unaligned and mixed-endian data access is
+ supported. This architecture includes the first version of Thumb
+ technology.
+ .
+ This feature is not guaranteed by the architecture baseline, but is
+ available for newer armel machines in the ARM11 product family, including
+ ARM1136J(F)-S, ARM1156T2(F)-S, ARM1176JZ(F)-S, ARM1136EJ(F)-S, and
+ ARM11MPCore processors. Boards include the Raspberry Pi model 1 and
+ Raspberry Pi Zero.
+
+Name: ARMv6K
+Architecture: armel
+Priority: 6900
+Test: return !(need_armv_version(6) && (getauxval(AT_HWCAP) & HWCAP_ARM_TLS));
+#qemu-good: "qemu-$DEB_HOST_MULTIARCH_CPU""$QEMU_EXTRA" -cpu arm1136
+#qemu-bad: "qemu-$DEB_HOST_MULTIARCH_CPU""$QEMU_EXTRA" -cpu arm1136-r2
+Package: yes
+Description:
+ ARMv6k is a subarchitecture of ARMV6 adding Symmetric MultiProcessing
+ and Thread Local Storage instruction sets. It is not guaranteed by the
+ architecture baseline, but is available for newer armel machines in the
+ ARM11 product family; boards include the Raspberry Pi model 1 and
+ Raspberry Pi Zero.
+
+Name: ARMv7
+Architecture: armel
+Test: return !need_armv_version(7);
+#qemu-bad: "qemu-$DEB_HOST_MULTIARCH_CPU""$QEMU_EXTRA" -cpu arm1136
+#qemu-good: "qemu-$DEB_HOST_MULTIARCH_CPU""$QEMU_EXTRA" -cpu cortex-a7
+Priority: 7000
+Package: yes
+Description:
+ ARMv7 (not to be confused with product family ARM7) includes Thumb-2
+ technology, adding 32-bit instructions into compressed Thumb mode. It is
+ not guaranteed by the architecture baseline, but is available for newer
+ armel machines (including CPUs that support armhf) since the Cortex-A
+ product family, including Cortex-A5, -A7, -A8, -A9, -A12, -A15, and -A17
+ processors. Boards include the Raspberry Pi 2.
+
+Name: ARMv8
+Architecture: armel armhf
+Test: return !need_armv_version(8);
+Package: yes
+Priority: 8000
+Description:
+ ARMv8 (not to be confused with product family ARM8) introduced a large
+ number of ISA enhancements. It is not guaranteed by the architecture
+ baseline, but is available for newer armel machines (including CPUs that
+ support armhf) since the Cortex-A product family, including Cortex-A32, as
+ well as all arm64 processors. Boards include the Raspberry Pi 3 and 4.
+
+Name: VFP
+Architecture: armel
+Test: return !(getauxval(AT_HWCAP) & HWCAP_ARM_VFP)
+#qemu-bad: "qemu-$DEB_HOST_MULTIARCH_CPU""$QEMU_EXTRA" -cpu arm926
+#qemu-good: "qemu-$DEB_HOST_MULTIARCH_CPU""$QEMU_EXTRA" -cpu arm1136
+Package: yes
+Description:
+ VFP (Vector Floating Point) technology is a floating-point unit (FPU)
+ coprocessor extension to the ARM architecture. It provides single- and
+ double-precision floating-point computation fully compliant with IEEE
+ 754-1985.
+
+Name: VFPv2
+Architecture: armel
+Test: return !(need_armv_version(5) && (getauxval(AT_HWCAP) & HWCAP_ARM_VFP))
+#qemu-bad: "qemu-$DEB_HOST_MULTIARCH_CPU""$QEMU_EXTRA" -cpu arm926
+#qemu-good: "qemu-$DEB_HOST_MULTIARCH_CPU""$QEMU_EXTRA" -cpu arm1136
+Package: yes
+Description:
+ VFP (Vector Floating Point) technology is a floating-point unit (FPU)
+ coprocessor extension to the ARM architecture. It provides single- and
+ double-precision floating-point computation fully compliant with IEEE
+ 754-1985.
+ .
+ VFPv2 has 16 64-bit FPU registers. It is available for some ARMv5 and
+ all ARMv6 cores.
+
+Name: VFPv3
+Architecture: armel
+Test: return !(getauxval(AT_HWCAP) & HWCAP_ARM_VFPv3)
+#qemu-bad: "qemu-$DEB_HOST_MULTIARCH_CPU""$QEMU_EXTRA" -cpu arm1136
+#qemu-good: "qemu-$DEB_HOST_MULTIARCH_CPU""$QEMU_EXTRA" -cpu cortex-a8
+Package: yes
+Description:
+ VFP (Vector Floating Point) technology is a floating-point unit (FPU)
+ coprocessor extension to the ARM architecture. It provides single- and
+ double-precision floating-point computation fully compliant with IEEE
+ 754-1985.
+ .
+ VFPv3 has 32 64-bit FPU registers as standard, adds VCVT instructions to
+ convert between scalar, float, and double, and adds immediate mode to VMOV,
+ allowing constants to be loaded into FPU registers. It is available on most
+ Cortex-A8 and -A9 ARMv7 processors.
diff --git a/qemu-@QEMUTYPE@-@NAME@ b/qemu-@QEMUTYPE@-@NAME@
new file mode 100755
index 0000000..63b21d7
--- /dev/null
+++ b/qemu-@QEMUTYPE@-@NAME@
@@ -0,0 +1,10 @@
+#!/bin/sh
+
+DEB_HOST_ARCH='@DEB_HOST_ARCH@'
+DEB_HOST_ARCH_CPU='@DEB_HOST_ARCH_CPU@'
+DEB_HOST_ARCH_BITS='@DEB_HOST_ARCH_BITS@'
+DEB_HOST_MULTIARCH='@DEB_HOST_MULTIARCH@'
+DEB_HOST_MULTIARCH_CPU='@DEB_HOST_MULTIARCH_CPU@'
+QEMU_EXTRA='@QEMU_EXTRA@'
+
+exec @QEMU@ "$@"
diff --git a/refresh-package b/refresh-package
new file mode 100755
index 0000000..ce6e505
--- /dev/null
+++ b/refresh-package
@@ -0,0 +1,210 @@
+#!/usr/bin/perl -w
+undef $/;
+my $DEB_HOST_MULTIARCH =
+ ( split /\n/, qx/dpkg-architecture -qDEB_HOST_MULTIARCH/ )[0];
+my $DEB_HOST_ARCH = ( split /\n/, qx/dpkg-architecture -qDEB_HOST_ARCH/ )[0];
+my $DEB_HOST_ARCH_BITS =
+ ( split /\n/, qx/dpkg-architecture -qDEB_HOST_ARCH_BITS/ )[0];
+my $DEB_HOST_ARCH_CPU =
+ ( split /\n/, qx/dpkg-architecture -qDEB_HOST_ARCH_CPU/ )[0];
+my $DEB_HOST_MULTIARCH_CPU = $DEB_HOST_MULTIARCH;
+$DEB_HOST_MULTIARCH_CPU =~ s/^([^-]+?)-.*$/$1/g;
+
+my $version = ( split /\n/, qx/dpkg-parsechangelog --show-field Version/ )[0];
+
+sub file_replace {
+ my ( $f, $name, $lcname ) = @_;
+ my $foutname = $f;
+ $foutname =~ s/[@]NAME[@]/$name/;
+ $foutname =~ s/[@]LCNAME[@]/$lcname/;
+ open IN, "<debian/$f.in" or die "Can't read debian/$f.in: $!\n";
+ local $_ = <IN>;
+ close IN;
+
+ s/[@]NAME[@]/$name/g;
+ s/[@]LCNAME[@]/$lcname/g;
+ s/[@]DEB_HOST_MULTIARCH[@]/$DEB_HOST_MULTIARCH/g;
+ open OUT, ">debian/$foutname"
+ or die "Can't write debian/$foutname: $!\n";
+ print OUT;
+ close OUT;
+}
+
+my $control;
+
+my $ctemplate;
+my $cfilename = 'test-@NAME@.c';
+open( my $fctemplate, '<', $cfilename ) or die "cannot open file $cfilename";
+{
+ local $/ = undef;
+ $ctemplate = <$fctemplate>;
+}
+close($fctemplate);
+
+# dpkg-shlibdeps now looks inside, but is ok with an empty file.
+system("touch debian/control");
+
+my @control_in;
+open IN, "<debian/control.d/control.in"
+ or die "Can't read debian/control.d/control.in: $!\n";
+$_ = <IN>;
+@control_in = grep !/^\s*$/s, split /\n\s*\n/s;
+close IN;
+
+my @controltest_in;
+open IN, "<debian/tests/control.in"
+ or die "Can't read debian/tests/control.in: $!\n";
+$_ = <IN>;
+@controltest_in = grep !/^\s*$/s, split /\n\s*\n/s;
+close IN;
+
+open ISA_LIST, "<isa-list" or die "Can't read isa-list: $!\n";
+$_ = <ISA_LIST>;
+close ISA_LIST;
+my %archlist;
+
+my @structs;
+foreach my $block ( split /\n\s*\n/s ) {
+ my $lastfield = undef;
+ my %data = ();
+ foreach ( split /\n/s, $block ) {
+ next if /^#.*/;
+ next if /^\s*$/;
+ if (/^([^\s:]+?)\s*:\s*(.*?)\s*$/) {
+ $key = $1;
+ $value = $2 // '';
+ $data{"$key"} = "$value";
+ $lastfield = "$key";
+ }
+ elsif (/^(\s+\S.*?)\s*$/) {
+ $data{$lastfield} .= "\n$1";
+ }
+
+ next;
+ }
+ if (%data) {
+ $data{"Package"} = "no" if !exists( $data{"Package"} );
+ push @structs, \%data;
+ }
+}
+
+my $controltest = '';
+
+for (@structs) {
+ my %entry = %$_;
+ $archlist{ $entry{'Architecture'} } = 1;
+ my $name = $entry{'Name'};
+ my $lcname = lc($name);
+ $name =~ /^[a-zA-Z0-9\.+_-]+$/ or die "Bad package/isa name: \"$name\".\n";
+ my $description = $entry{'Description'};
+ $description =~ s/\A\s*\n+//m;
+ $description =~ s/\A\s+//m;
+
+ if ( $entry{'Package'} =~ /yes/i ) {
+ my @c = @control_in;
+ foreach (@c) {
+ s/[@]NAME[@]/$name/g;
+ s/[@]LCNAME[@]/$lcname/g;
+ s/[@]ARCHITECTURE[@]/$entry{'Architecture'}/g;
+ s/[@]DEB_HOST_MULTIARCH[@]/$DEB_HOST_MULTIARCH/g;
+ s/[@]DESCRIPTION[@]/$description/g;
+ $control .= "\n" . $_;
+ }
+ }
+
+ open C, '>', "test-$name.c";
+ my $test = $entry{'Test'} // "return !__builtin_cpu_supports(\"$lcname\");";
+ my $cfile = $ctemplate;
+ $cfile =~ s/[@]TEST[@]/$test/gm;
+ $cfile =~ s/[@]NAME[@]/$name/g;
+ $cfile =~ s/[@]VERSION[@]/$version/g;
+ my $cdescription = $description;
+ $cdescription =~ s/"/\"/gm;
+ $cdescription =~ s/^\s//gm;
+ $cdescription =~ s/^[.]\n/\n/gm;
+ $cdescription =~ s/\n/\\n\"\n \"/gm;
+ $cfile =~ s/[@]DESCRIPTION[@]/$description/g;
+ $cfile =~ s/[@]CDESCRIPTION[@]/$cdescription/g;
+
+ print C $cfile;
+ close C;
+
+ for my $qemutype (qw(good bad static-bad static-good)) {
+ my $qemu = $qemutype;
+ $qemu =~ s/^static-//g;
+ if ( exists $entry{ 'qemu-' . $qemu } ) {
+ my $qemu_extra = '';
+ $qemu_extra .= '-static' if ( $qemutype =~ '^static-' );
+
+ my $finname = 'qemu-' . '@QEMUTYPE@-@NAME@';
+ my $foutname = $finname;
+ $foutname =~ s/[@]NAME[@]/$name/;
+ $foutname =~ s/[@]QEMUTYPE[@]/$qemutype/;
+ open IN, "<$finname" or die "Can't read $finname: $!\n";
+ local $_ = <IN>;
+ close IN;
+
+ s/[@]NAME[@]/$name/g;
+ s/[@]DEB_HOST_MULTIARCH[@]/$DEB_HOST_MULTIARCH/g;
+ s/[@]DEB_HOST_MULTIARCH_CPU[@]/$DEB_HOST_MULTIARCH_CPU/g;
+ s/[@]DEB_HOST_ARCH[@]/$DEB_HOST_ARCH/g;
+ s/[@]DEB_HOST_ARCH_BITS[@]/$DEB_HOST_ARCH_BITS/g;
+ s/[@]DEB_HOST_ARCH_CPU[@]/$DEB_HOST_ARCH_CPU/g;
+ if ( $qemutype =~ 'good$' ) {
+ s/[@]QEMU[@]/$entry{'qemu-good'}/g;
+ }
+ else {
+ s/[@]QEMU[@]/$entry{'qemu-bad'}/g;
+ }
+ s/[@]QEMU_EXTRA[@]/$qemu_extra/g;
+
+ open OUT, ">$foutname"
+ or die "Can't write $foutname: $!\n";
+ print OUT;
+ close OUT;
+ }
+ }
+
+ if ( exists $entry{'qemu-good'} and exists $entry{'qemu-bad'} ) {
+ my @c = @controltest_in;
+ foreach (@c) {
+ s/[@]NAME[@]/$name/g;
+ s/[@]LCNAME[@]/$lcname/g;
+ s/[@]ARCHITECTURE[@]/$entry{'Architecture'}/g;
+ s/[@]DEB_HOST_MULTIARCH[@]/$DEB_HOST_MULTIARCH/g;
+ s/[@]DESCRIPTION[@]/$description/g;
+ $controltest .= $_ . "\n";
+ }
+ file_replace( 'tests/test-@NAME@', $name, $lcname );
+ chmod 0777, "debian/tests/test-$name";
+ }
+
+ foreach (
+ qw(@LCNAME@-support.preinst @LCNAME@-support.templates @LCNAME@-support.lintian-overrides @LCNAME@-support.maintscript)
+ )
+ {
+ file_replace( $_, $name, $lcname );
+ }
+}
+
+my $all_architectures = join( ' ', sort( keys %archlist ) );
+
+my $control_base;
+my $filename = "debian/control.d/control-base.in";
+open( my $fh, '<', $filename ) or die "cannot open file $filename";
+{
+ local $/ = undef;
+ $control_base = <$fh>;
+}
+close($fh);
+$control_base =~ s/[@]ALL_ARCHITECTURES[@]/$all_architectures/g;
+$control = $control_base . $control;
+
+open CONTROL, ">debian/control" or die "Can't write to debian/control: $!\n";
+print CONTROL $control;
+close CONTROL;
+
+open CONTROLTEST, ">debian/tests/control"
+ or die "Can't write to debian/tests/control: $!\n";
+print CONTROLTEST $controltest;
+close CONTROLTEST;
diff --git a/test-@NAME@.c b/test-@NAME@.c
new file mode 100644
index 0000000..47845e1
--- /dev/null
+++ b/test-@NAME@.c
@@ -0,0 +1,75 @@
+#include <stdbool.h>
+#include <sys/resource.h>
+#include <signal.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <string.h>
+
+#include <argp.h>
+
+#include <sys/auxv.h>
+
+#if defined(__x86_64__) || defined(__i386__)
+#include <sys/platform/x86.h>
+#endif
+
+const char *argp_program_version = "test-@NAME@ version @VERSION@";
+static char doc[] = "return success if @NAME@\n"
+ "\n"
+ "@CDESCRIPTION@";
+static struct argp argp = { 0, 0, 0, doc };
+
+#ifdef AT_PLATFORM
+/* detect ARM ABI version will be optimized away if not used */
+static inline bool need_armv_version(int atleastversion)
+{
+ int version;
+ const char * platform = (const char *)getauxval(AT_PLATFORM);
+ if (platform == NULL)
+ return false;
+ /* at least v5 */
+ if (strlen(platform) < strlen("v5"))
+ return false;
+ if (*(platform++) != 'v')
+ return false;
+
+ char *endstr;
+ errno = 0;
+ version = strtol(platform,&endstr,10);
+ if (errno != 0)
+ return false;
+ if (endstr == platform)
+ return false;
+
+ return (version >= atleastversion);
+
+}
+#endif
+
+const struct rlimit nocore = { 0, 0 };
+
+/* emulate kill by signal */
+void
+termination_handler (int signum)
+{
+ _exit(128+signum);
+}
+
+int main(int argc,char **argv)
+{
+ /* no core */
+ (void) setrlimit(RLIMIT_CORE, &nocore);
+ /* return instead */
+ struct sigaction new_action;
+ new_action.sa_handler = termination_handler;
+ (void) sigemptyset (&new_action.sa_mask);
+ new_action.sa_flags = 0;
+ (void) sigaction (SIGILL, &new_action, NULL);
+ (void) sigaction (SIGBUS, &new_action, NULL);
+ (void) sigaction (SIGSEGV, &new_action, NULL);
+ argp_parse (&argp, argc, argv, 0, 0, 0);
+ /* now test */
+ @TEST@;
+ return 0;
+}