diff options
-rw-r--r-- | Makefile | 60 | ||||
-rw-r--r-- | README | 21 | ||||
-rwxr-xr-x | expand-translations | 29 | ||||
-rw-r--r-- | isa-list | 164 | ||||
-rw-r--r-- | qemu-bad-@NAME@ | 6 | ||||
-rw-r--r-- | qemu-bad-SSE2 | 6 | ||||
-rw-r--r-- | qemu-bad-SSE3 | 6 | ||||
-rw-r--r-- | qemu-bad-SSE4.1 | 6 | ||||
-rw-r--r-- | qemu-bad-SSE4.2 | 6 | ||||
-rw-r--r-- | qemu-good-@NAME@ | 6 | ||||
-rw-r--r-- | qemu-good-SSE2 | 6 | ||||
-rw-r--r-- | qemu-good-SSE3 | 6 | ||||
-rw-r--r-- | qemu-good-SSE4.1 | 6 | ||||
-rw-r--r-- | qemu-good-SSE4.2 | 6 | ||||
-rwxr-xr-x | refresh-package | 144 | ||||
-rw-r--r-- | test-@NAME@.c | 63 | ||||
-rw-r--r-- | test-ARMv6.c | 63 | ||||
-rw-r--r-- | test-ARMv6K.c | 63 | ||||
-rw-r--r-- | test-ARMv7.c | 63 | ||||
-rw-r--r-- | test-ARMv8.c | 63 | ||||
-rw-r--r-- | test-SSE2.c | 63 | ||||
-rw-r--r-- | test-VFP.c | 63 | ||||
-rw-r--r-- | test-VFPv2.c | 63 | ||||
-rw-r--r-- | test-VFPv3.c | 63 | ||||
-rw-r--r-- | test-altivec.c | 63 | ||||
-rw-r--r-- | test-neon.c | 63 |
26 files changed, 1171 insertions, 0 deletions
diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..a2c35d2 --- /dev/null +++ b/Makefile @@ -0,0 +1,60 @@ +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 isa,$(ISAS),qemu-good-$(isa)) $(foreach isa,$(ISAS),qemu-bad-$(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 + +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 $(TEST_BINARIES) + rm -f $(GENERATED_FILES) + 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..1a357bc --- /dev/null +++ b/isa-list @@ -0,0 +1,164 @@ +# 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. + +Name: SSE2 +Architecture: any-i386 +qemu-good: qemu-$DEB_HOST_ARCH -cpu "qemu$DEB_HOST_ARCH_BITS" +qemu-bad: qemu-$DEB_HOST_ARCH -cpu "qemu$DEB_HOST_ARCH_BITS",-see2,-sse3,-ssse3,-sse4.1,-sse4.2 +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: SSE3 +Architecture: any-i386 any-amd64 +qemu-good: qemu-$DEB_HOST_ARCH -cpu "qemu$DEB_HOST_ARCH_BITS" +qemu-bad: qemu-$DEB_HOST_ARCH -cpu "qemu$DEB_HOST_ARCH_BITS",-sse3,-ssse3,-sse4.1,-sse4.2 +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_ARCH -cpu "qemu$DEB_HOST_ARCH_BITS" +qemu-bad: qemu-$DEB_HOST_ARCH -cpu "qemu$DEB_HOST_ARCH_BITS",-sse4.1,-sse4.2 +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_ARCH -cpu "qemu$DEB_HOST_ARCH_BITS" +qemu-bad: qemu-$DEB_HOST_ARCH -cpu "qemu$DEB_HOST_ARCH_BITS",-sse4.2 +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: altivec +Architecture: powerpc +Test: asm volatile("vsldoi %v1,%v1,%v1,0"); +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"); +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); +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 +Test: return !(need_armv_version(6) && (getauxval(AT_HWCAP) & HWCAP_ARM_TLS)); +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); +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); +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) +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)) +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) +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-bad-@NAME@ b/qemu-bad-@NAME@ new file mode 100644 index 0000000..186d6e1 --- /dev/null +++ b/qemu-bad-@NAME@ @@ -0,0 +1,6 @@ +#!/bin/sh + +DEB_HOST_ARCH=@DEB_HOST_ARCH@ +DEB_HOST_ARCH_BITS=@DEB_HOST_ARCH_BITS@ + +exec @QEMU_BAD@ diff --git a/qemu-bad-SSE2 b/qemu-bad-SSE2 new file mode 100644 index 0000000..60c034c --- /dev/null +++ b/qemu-bad-SSE2 @@ -0,0 +1,6 @@ +#!/bin/sh + +DEB_HOST_ARCH=amd64 +DEB_HOST_ARCH_BITS=64 + +exec qemu-$DEB_HOST_ARCH -cpu "qemu$DEB_HOST_ARCH_BITS",-see2,-sse3,-ssse3,-sse4.1,-sse4.2 diff --git a/qemu-bad-SSE3 b/qemu-bad-SSE3 new file mode 100644 index 0000000..50f5318 --- /dev/null +++ b/qemu-bad-SSE3 @@ -0,0 +1,6 @@ +#!/bin/sh + +DEB_HOST_ARCH=amd64 +DEB_HOST_ARCH_BITS=64 + +exec qemu-$DEB_HOST_ARCH -cpu "qemu$DEB_HOST_ARCH_BITS",-sse3,-ssse3,-sse4.1,-sse4.2 diff --git a/qemu-bad-SSE4.1 b/qemu-bad-SSE4.1 new file mode 100644 index 0000000..9d9d28a --- /dev/null +++ b/qemu-bad-SSE4.1 @@ -0,0 +1,6 @@ +#!/bin/sh + +DEB_HOST_ARCH=amd64 +DEB_HOST_ARCH_BITS=64 + +exec qemu-$DEB_HOST_ARCH -cpu "qemu$DEB_HOST_ARCH_BITS",-sse4.1,-sse4.2 diff --git a/qemu-bad-SSE4.2 b/qemu-bad-SSE4.2 new file mode 100644 index 0000000..0c2cb9c --- /dev/null +++ b/qemu-bad-SSE4.2 @@ -0,0 +1,6 @@ +#!/bin/sh + +DEB_HOST_ARCH=amd64 +DEB_HOST_ARCH_BITS=64 + +exec qemu-$DEB_HOST_ARCH -cpu "qemu$DEB_HOST_ARCH_BITS",-sse4.2 diff --git a/qemu-good-@NAME@ b/qemu-good-@NAME@ new file mode 100644 index 0000000..db74d82 --- /dev/null +++ b/qemu-good-@NAME@ @@ -0,0 +1,6 @@ +#!/bin/sh + +DEB_HOST_ARCH=@DEB_HOST_ARCH@ +DEB_HOST_ARCH_BITS=@DEB_HOST_ARCH_BITS@ + +exec @QEMU_GOOD@ diff --git a/qemu-good-SSE2 b/qemu-good-SSE2 new file mode 100644 index 0000000..bf9d45a --- /dev/null +++ b/qemu-good-SSE2 @@ -0,0 +1,6 @@ +#!/bin/sh + +DEB_HOST_ARCH=amd64 +DEB_HOST_ARCH_BITS=64 + +exec qemu-$DEB_HOST_ARCH -cpu "qemu$DEB_HOST_ARCH_BITS" diff --git a/qemu-good-SSE3 b/qemu-good-SSE3 new file mode 100644 index 0000000..bf9d45a --- /dev/null +++ b/qemu-good-SSE3 @@ -0,0 +1,6 @@ +#!/bin/sh + +DEB_HOST_ARCH=amd64 +DEB_HOST_ARCH_BITS=64 + +exec qemu-$DEB_HOST_ARCH -cpu "qemu$DEB_HOST_ARCH_BITS" diff --git a/qemu-good-SSE4.1 b/qemu-good-SSE4.1 new file mode 100644 index 0000000..bf9d45a --- /dev/null +++ b/qemu-good-SSE4.1 @@ -0,0 +1,6 @@ +#!/bin/sh + +DEB_HOST_ARCH=amd64 +DEB_HOST_ARCH_BITS=64 + +exec qemu-$DEB_HOST_ARCH -cpu "qemu$DEB_HOST_ARCH_BITS" diff --git a/qemu-good-SSE4.2 b/qemu-good-SSE4.2 new file mode 100644 index 0000000..bf9d45a --- /dev/null +++ b/qemu-good-SSE4.2 @@ -0,0 +1,6 @@ +#!/bin/sh + +DEB_HOST_ARCH=amd64 +DEB_HOST_ARCH_BITS=64 + +exec qemu-$DEB_HOST_ARCH -cpu "qemu$DEB_HOST_ARCH_BITS" diff --git a/refresh-package b/refresh-package new file mode 100755 index 0000000..8f6e4a9 --- /dev/null +++ b/refresh-package @@ -0,0 +1,144 @@ +#!/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]; + +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; + +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; + } + push @structs, \%data if %data; + +} + +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; + + 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/g; + print C $cfile; + close C; + + for my $qemu (qw(qemu-good qemu-bad)) { + if (exists $entry{$qemu}) { + my $finname = $qemu.'-@NAME@'; + my $foutname = $finname; + $foutname =~ s/[@]NAME[@]/$name/; + 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_ARCH[@]/$DEB_HOST_ARCH/g; + s/[@]DEB_HOST_ARCH_BITS[@]/$DEB_HOST_ARCH_BITS/g; + s/[@]QEMU_GOOD[@]/$entry{'qemu-good'}/g; + s/[@]QEMU_BAD[@]/$entry{'qemu-bad'}/g; + + open OUT, ">$foutname" + or die "Can't write $foutname: $!\n"; + print OUT; + close OUT; + } + } + + 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; diff --git a/test-@NAME@.c b/test-@NAME@.c new file mode 100644 index 0000000..2900044 --- /dev/null +++ b/test-@NAME@.c @@ -0,0 +1,63 @@ +#include <stdbool.h> +#include <sys/resource.h> +#include <signal.h> +#include <unistd.h> +#include <stdlib.h> +#include <errno.h> +#include <string.h> + + +#include <sys/auxv.h> + +#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() +{ + /* 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); + /* now test */ + @TEST@; + return 0; +} diff --git a/test-ARMv6.c b/test-ARMv6.c new file mode 100644 index 0000000..a2abf51 --- /dev/null +++ b/test-ARMv6.c @@ -0,0 +1,63 @@ +#include <stdbool.h> +#include <sys/resource.h> +#include <signal.h> +#include <unistd.h> +#include <stdlib.h> +#include <errno.h> +#include <string.h> + + +#include <sys/auxv.h> + +#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() +{ + /* 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); + /* now test */ + return !need_armv_version(6);; + return 0; +} diff --git a/test-ARMv6K.c b/test-ARMv6K.c new file mode 100644 index 0000000..537877f --- /dev/null +++ b/test-ARMv6K.c @@ -0,0 +1,63 @@ +#include <stdbool.h> +#include <sys/resource.h> +#include <signal.h> +#include <unistd.h> +#include <stdlib.h> +#include <errno.h> +#include <string.h> + + +#include <sys/auxv.h> + +#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() +{ + /* 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); + /* now test */ + return !(need_armv_version(6) && (getauxval(AT_HWCAP) & HWCAP_ARM_TLS));; + return 0; +} diff --git a/test-ARMv7.c b/test-ARMv7.c new file mode 100644 index 0000000..3587c27 --- /dev/null +++ b/test-ARMv7.c @@ -0,0 +1,63 @@ +#include <stdbool.h> +#include <sys/resource.h> +#include <signal.h> +#include <unistd.h> +#include <stdlib.h> +#include <errno.h> +#include <string.h> + + +#include <sys/auxv.h> + +#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() +{ + /* 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); + /* now test */ + return !need_armv_version(7);; + return 0; +} diff --git a/test-ARMv8.c b/test-ARMv8.c new file mode 100644 index 0000000..f22a034 --- /dev/null +++ b/test-ARMv8.c @@ -0,0 +1,63 @@ +#include <stdbool.h> +#include <sys/resource.h> +#include <signal.h> +#include <unistd.h> +#include <stdlib.h> +#include <errno.h> +#include <string.h> + + +#include <sys/auxv.h> + +#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() +{ + /* 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); + /* now test */ + return !need_armv_version(8);; + return 0; +} diff --git a/test-SSE2.c b/test-SSE2.c new file mode 100644 index 0000000..3909525 --- /dev/null +++ b/test-SSE2.c @@ -0,0 +1,63 @@ +#include <stdbool.h> +#include <sys/resource.h> +#include <signal.h> +#include <unistd.h> +#include <stdlib.h> +#include <errno.h> +#include <string.h> + + +#include <sys/auxv.h> + +#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() +{ + /* 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); + /* now test */ + return !__builtin_cpu_supports("sse2");; + return 0; +} diff --git a/test-VFP.c b/test-VFP.c new file mode 100644 index 0000000..2ba4dd2 --- /dev/null +++ b/test-VFP.c @@ -0,0 +1,63 @@ +#include <stdbool.h> +#include <sys/resource.h> +#include <signal.h> +#include <unistd.h> +#include <stdlib.h> +#include <errno.h> +#include <string.h> + + +#include <sys/auxv.h> + +#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() +{ + /* 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); + /* now test */ + return !(getauxval(AT_HWCAP) & HWCAP_ARM_VFP); + return 0; +} diff --git a/test-VFPv2.c b/test-VFPv2.c new file mode 100644 index 0000000..2db7547 --- /dev/null +++ b/test-VFPv2.c @@ -0,0 +1,63 @@ +#include <stdbool.h> +#include <sys/resource.h> +#include <signal.h> +#include <unistd.h> +#include <stdlib.h> +#include <errno.h> +#include <string.h> + + +#include <sys/auxv.h> + +#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() +{ + /* 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); + /* now test */ + return !(need_armv_version(5) && (getauxval(AT_HWCAP) & HWCAP_ARM_VFP)); + return 0; +} diff --git a/test-VFPv3.c b/test-VFPv3.c new file mode 100644 index 0000000..502a4f3 --- /dev/null +++ b/test-VFPv3.c @@ -0,0 +1,63 @@ +#include <stdbool.h> +#include <sys/resource.h> +#include <signal.h> +#include <unistd.h> +#include <stdlib.h> +#include <errno.h> +#include <string.h> + + +#include <sys/auxv.h> + +#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() +{ + /* 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); + /* now test */ + return !(getauxval(AT_HWCAP) & HWCAP_ARM_VFPv3); + return 0; +} diff --git a/test-altivec.c b/test-altivec.c new file mode 100644 index 0000000..4c441f8 --- /dev/null +++ b/test-altivec.c @@ -0,0 +1,63 @@ +#include <stdbool.h> +#include <sys/resource.h> +#include <signal.h> +#include <unistd.h> +#include <stdlib.h> +#include <errno.h> +#include <string.h> + + +#include <sys/auxv.h> + +#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() +{ + /* 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); + /* now test */ + asm volatile("vsldoi %v1,%v1,%v1,0");; + return 0; +} diff --git a/test-neon.c b/test-neon.c new file mode 100644 index 0000000..88a932c --- /dev/null +++ b/test-neon.c @@ -0,0 +1,63 @@ +#include <stdbool.h> +#include <sys/resource.h> +#include <signal.h> +#include <unistd.h> +#include <stdlib.h> +#include <errno.h> +#include <string.h> + + +#include <sys/auxv.h> + +#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() +{ + /* 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); + /* now test */ + asm volatile("VMUL.I16 q0,q0,q1");; + return 0; +} |