diff options
-rw-r--r-- | Makefile | 61 | ||||
-rw-r--r-- | README | 21 | ||||
-rwxr-xr-x | expand-translations | 29 | ||||
-rw-r--r-- | isa-list | 351 | ||||
-rwxr-xr-x | qemu-@QEMUTYPE@-@NAME@ | 10 | ||||
-rwxr-xr-x | refresh-package | 210 | ||||
-rw-r--r-- | test-@NAME@.c | 75 |
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 @@ -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; +} |