summaryrefslogtreecommitdiff
path: root/testsuite
diff options
context:
space:
mode:
authorDavid Schleef <ds@schleef.org>2005-06-16 06:46:06 +0000
committerDavid Schleef <ds@schleef.org>2005-06-16 06:46:06 +0000
commit508ba3985f38081917b76fcfc4ac84e73ca2954a (patch)
treebd56b3f8c781a82c6f018a6d4a03d2c33fdd7a5b /testsuite
parent7ffccb74ac2ebfd0b6f8361d4016b0ceb3c9581f (diff)
downloadliboil-508ba3985f38081917b76fcfc4ac84e73ca2954a.tar.gz
* configure.ac: Add instruction checker
* testsuite/Makefile.am: * testsuite/instruction/Makefile.am: * testsuite/instruction/check-instructions.pl: * testsuite/instruction/list-impls.c: (main): * liboil/colorspace/argb_paint_i386.c: Fix flags based on advice of the instruction checker * liboil/colorspace/ayuv2argb_i386.c: * liboil/conv/conv_3dnow.c: * liboil/conv/conv_sse.c: * liboil/copy/trans8x8_i386.c: * liboil/dct/idct8x8_i386.c: * liboil/sse/conv_sse.c: * liboil/liboilfuncs.h: update * liboil/liboilmarshal.c: (_oil_test_marshal_function): update * liboil/liboiltest.c: (oil_test_new), (oil_test_check_function): regenerate inplace data for every test iteration. Bump default n to 1000 to force memcpy to choose a good function. (lame hack) * liboil/copy/copy_i386.c: (copy_u8_mmx3), (copy_u8_mmx4), (copy_u8_mmx5): new implementation, fix others * liboil/copy/splat_i386.c: (splat_u32_ns_mmx): make faster * liboil/copy/splat_ref.c: (splat_u8_ns_int): fix bug * liboil/colorspace/argb_paint.c: (argb_splat_u8_ref), (rgba_splat_u8_ref): New functions * liboil/simdpack/average2_u8.c: (average2_u8_ref), (average2_u8_trick), (average2_u8_fast), (average2_u8_unroll4): Implementations really need to follow stride rules. * liboil/Makefile.am: Don't use SSE flags, because people on powerpc don't appreciate it. * examples/memcpy-speed.c: (main): only go to 1<<24 bytes
Diffstat (limited to 'testsuite')
-rw-r--r--testsuite/Makefile.am2
-rw-r--r--testsuite/instruction/Makefile.am15
-rwxr-xr-xtestsuite/instruction/check-instructions.pl444
-rw-r--r--testsuite/instruction/list-impls.c83
4 files changed, 544 insertions, 0 deletions
diff --git a/testsuite/Makefile.am b/testsuite/Makefile.am
index 0bc4c72..db7c347 100644
--- a/testsuite/Makefile.am
+++ b/testsuite/Makefile.am
@@ -1,4 +1,6 @@
+SUBDIRS = instruction
+
if HAVE_GLIB
glib_programs = abs md5 md5_profile trans copy
else
diff --git a/testsuite/instruction/Makefile.am b/testsuite/instruction/Makefile.am
new file mode 100644
index 0000000..804d643
--- /dev/null
+++ b/testsuite/instruction/Makefile.am
@@ -0,0 +1,15 @@
+
+noinst_PROGRAMS = list-impls
+
+noinst_DATA = report
+
+AM_LDFLAGS = $(LIBOIL_LIBS)
+AM_CFLAGS = $(LIBOIL_CFLAGS)
+
+
+report: list-impls
+ ./check-instructions.pl $(top_builddir)/liboil/.libs/liboiltmp1.so >report
+
+
+EXTRA_CLEAN = report
+
diff --git a/testsuite/instruction/check-instructions.pl b/testsuite/instruction/check-instructions.pl
new file mode 100755
index 0000000..fa250ee
--- /dev/null
+++ b/testsuite/instruction/check-instructions.pl
@@ -0,0 +1,444 @@
+#!/usr/bin/perl -w
+# vi: set ts=4:
+#
+
+$debug = 0;
+
+sub get_flags
+{
+ my @list = @insns;
+ my $exts = {};
+ my $s;
+
+ $debug && print "function: $func\n";
+ foreach $insn (@list) {
+ if (grep { /^$insn$/ } @normal_list) {
+ $debug && print " $insn: normal\n";
+ }elsif (grep { /^$insn$/ } @mmx_list) {
+ $exts->{"mmx"} = 1;
+ $debug && print " $insn: mmx\n";
+ }elsif (grep { /^$insn$/ } @mmx_ext_list) {
+ $exts->{"mmxext"} = 1;
+ $debug && print " $insn: mmxext\n";
+ }elsif (grep { /^$insn$/ } @_3dnow_list) {
+ $exts->{"3dnow"} = 1;
+ $debug && print " $insn: 3dnow\n";
+ }elsif (grep { /^$insn$/ } @_3dnow_ext_list) {
+ $exts->{"3dnowext"} = 1;
+ $debug && print " $insn: 3dnowext\n";
+ }elsif (grep { /^$insn$/ } @sse_list) {
+ $exts->{"sse"} = 1;
+ $debug && print " $insn: sse\n";
+ }elsif (grep { /^$insn$/ } @sse2_list) {
+ $exts->{"sse2"} = 1;
+ $debug && print " $insn: sse2\n";
+ }else {
+ print "FIXME:\t\"$insn\",\n";
+ $error = 1;
+ }
+ }
+ $s = join(" ",sort(keys(%$exts)));
+ $funcs->{"$func"} = $s;
+ $debug && print " FLAGS: $s\n";
+}
+
+sub check
+{
+ foreach $insn (@normal_list) {
+ if (grep { /^$insn$/ } @mmx_list) {
+ print "FIXME: $insn is in mmx_list\n";
+ $error = 1;
+ } elsif (grep { /^$insn$/ } @mmx_ext_list) {
+ print "FIXME: $insn is in mmx_ext_list\n";
+ $error = 1;
+ } elsif (grep { /^$insn$/ } @_3dnow_list) {
+ print "FIXME: $insn is in _3dnow_list\n";
+ $error = 1;
+ } elsif (grep { /^$insn$/ } @_3dnow_ext_list) {
+ print "FIXME: $insn is in _3dnow_ext_list\n";
+ $error = 1;
+ } elsif (grep { /^$insn$/ } @sse_list) {
+ print "FIXME: $insn is in sse_list\n";
+ $error = 1;
+ } elsif (grep { /^$insn$/ } @sse2_list) {
+ print "FIXME: $insn is in sse2_list\n";
+ $error = 1;
+ }
+ }
+}
+
+@normal_list = (
+ "add",
+ "addl",
+ "and",
+ "andl",
+ "call",
+ "cld",
+ "cltd",
+ "cmovg",
+ "cmp",
+ "cmpb",
+ "cmpl",
+ "cwtl",
+ "dec",
+ "decl",
+ "fabs",
+ "fadd",
+ "faddl",
+ "faddp",
+ "fadds",
+ "fdivrl",
+ "fild",
+ "fildl",
+ "fildll",
+ "fistp",
+ "fistpl",
+ "fistpll",
+ "fldcw",
+ "fldl",
+ "flds",
+ "fldz",
+ "fmul",
+ "fmull",
+ "fmulp",
+ "fmuls",
+ "fnstcw",
+ "fnstsw",
+ "fsqrt",
+ "fstl",
+ "fstp",
+ "fstpl",
+ "fstps",
+ "fsts",
+ "fsub",
+ "fsubl",
+ "fsubp",
+ "fsubr",
+ "fsubrl",
+ "fsubrp",
+ "fucom",
+ "fucomp",
+ "fucompp",
+ "fxch",
+ "imul",
+ "inc",
+ "incl",
+ "ja",
+ "jae",
+ "jbe",
+ "je",
+ "jg",
+ "jge",
+ "jl",
+ "jle",
+ "jmp",
+ "jne",
+ "jns",
+ "jp",
+ "js",
+ "lea",
+ "leave",
+ "mov",
+ "movb",
+ "movl",
+ "movsbl",
+ "movsbw",
+ "movswl",
+ "movsww",
+ "movzbl",
+ "movzbw",
+ "movzwl",
+ "mulb",
+ "neg",
+ "nop",
+ "not",
+ "or",
+ "pop",
+ "push",
+ "pushl",
+ "repz",
+ "ret",
+ "rol",
+ "sahf",
+ "sar",
+ "sarl",
+ "shl",
+ "shr",
+ "sub",
+ "subl",
+ "test",
+ "testb",
+ "testl",
+ "xor",
+);
+
+# verified
+@mmx_list = (
+ "emms",
+ "movd",
+ "movq",
+ "packssdw",
+ "packsswb",
+ "packuswb",
+ "paddb",
+ "paddd",
+ "paddsb",
+ "paddsw",
+ "paddusb",
+ "paddusw",
+ "paddw",
+ "pand",
+ "pandn",
+ "pcmpeqb",
+ "pcmpeqd",
+ "pcmpgtb",
+ "pcmpgtd",
+ "pcmpgtw",
+ "pmaddwd",
+ "pmulhw",
+ "pmullw",
+ "por",
+ "pslld",
+ "psllq",
+ "psllw",
+ "psrad",
+ "psraw",
+ "psrld",
+ "psrlq",
+ "psrlw",
+ "psubb",
+ "psubd",
+ "psubsb",
+ "psubsw",
+ "psubusb",
+ "psubusw",
+ "psubw",
+ "punpckhbw",
+ "punpckhdq",
+ "punpckhwd",
+ "punpcklbw",
+ "punpckldq",
+ "punpcklwd",
+ "pxor"
+);
+
+# verified
+@_3dnow_list = (
+ "femms",
+ "pavgusb",
+ "pf2id",
+ "pfacc",
+ "pfadd",
+ "pfcmpeq",
+ "pfcmpge",
+ "pfcmpgt",
+ "pfmax",
+ "pfmin",
+ "pfmul",
+ "pfrcp",
+ "pfrcpit1",
+ "pfrcpit2",
+ "pfrsqit1",
+ "pfrsqrt",
+ "pfsub",
+ "pfsubr",
+ "pi2fd",
+ "pmulhrw",
+ "prefetch",
+ "prefetchw"
+);
+
+# verified
+@_3dnow_ext_list = (
+ "pf2iw",
+ "pfnacc",
+ "pfpnacc",
+ "pi2fw",
+ "pswapd"
+);
+
+# verified
+@mmx_ext_list = (
+ "maskmovq",
+ "movntq",
+ "pavgb",
+ "pavgw",
+ "pextrw",
+ "pinsrw",
+ "pmaxsw",
+ "pmaxub",
+ "pminsw",
+ "pminub",
+ "pmovmskb",
+ "pmulhuw",
+ "prefetchnta",
+ "prefetch0",
+ "prefetch1",
+ "prefetch2",
+ "psadbw",
+ "pshufw",
+ "sfence"
+);
+
+# verified
+@sse_list = (
+ "addps",
+ "addss",
+ "andnps",
+ "andps",
+ "cmpps",
+ "cmpss",
+ "comiss",
+ "cvtpi2ps",
+ "cvtps2ps",
+ "cvtsi2ss",
+ "cvtss2si",
+ "cvttps2pi",
+ "cvttss2si",
+ "divps",
+ "divss",
+ "fxrstor",
+ "fxsave",
+ "ldmxcsr",
+ "maxps",
+ "maxss",
+ "minps",
+ "minss",
+ "movaps",
+ "movhlps",
+ "movhps",
+ "movlhps",
+ "movlps",
+ "movmskps",
+ "movss",
+ "movups",
+ "mulps",
+ "mulss",
+ "orps",
+ "rcpps",
+ "rcpss",
+ "rsqrtps",
+ "rsqrtss",
+ "shufps",
+ "sqrtps",
+ "sqrtss",
+ "stmxcsr",
+ "subps",
+ "subss",
+ "ucomiss",
+ "unpckhps",
+ "unpcklps",
+ "xorps"
+);
+
+@sse2_list = (
+ "addpd",
+ "addsd",
+ "andnpd",
+ "andpd",
+ "cmppd",
+ "cmpsd",
+ "comisd",
+ "cvtpi2pd",
+ "cvtpd2pi",
+ "cvtsi2sd",
+ "cvtsd2si",
+ "cvttpd2pi",
+ "cvttsd2si",
+ "cvtpd2ps",
+ "cvtps2pd",
+ "cvtsd2ss",
+ "cvtss2sd",
+ "cvtps2dq",
+ "cvttpd2dq",
+ "cvtdq2pd",
+ "cvtps2dq",
+ "cvttps2dq",
+ "cvtdq2ps",
+ "divpd",
+ "divsd",
+ "maxpd",
+ "maxsd",
+ "minsd",
+ "movapd",
+ "movhpd",
+ "movlpd",
+ "movmskpd",
+ "movsd",
+ "movupd",
+ "mulpd",
+ "mulsd",
+ "orpd",
+ "shufpd",
+ "sqrtpd",
+ "sqrtsd",
+ "subpd",
+ "subsd",
+ "ucomisd",
+ "unpckhpd",
+ "unpcklpd",
+ "xorpd",
+);
+
+$funcs = {};
+
+$ARGV=shift @ARGV;
+@output=`objdump -dr $ARGV`;
+
+check();
+
+$error = 0;
+@insns = ();
+while($_=shift @output){
+ chomp;
+ if(m/^0[0-9a-fA-F]+\s<[\.\w]+>:$/){
+ $f = $_;
+ $f =~ s/^0[0-9a-fA-F]+\s<([\.\w]+)>:$/$1/;
+
+ if (@insns) {
+ get_flags ();
+ }
+
+ $func = $f;
+
+ @insns = ();
+ $debug && print "$func:\n";
+
+ } elsif(m/^[\s0-9a-f]+:\s[\s0-9a-f]+\s([a-z0-9]+)\s/){
+ if (!grep { /$1/ } @insns) {
+ push @insns, $1;
+ }
+ #print " $1\n";
+ } elsif (m/^$/) {
+ } elsif (m/^Disassembly of section/) {
+ } elsif (m/\sfile format\s/) {
+ } else {
+ print "FIXME: $_\n";
+ $error = 1;
+ }
+}
+
+@source = `./list-impls`;
+while ($_ = shift @source) {
+ chomp;
+ if (m/^([\w\.]+):\s*([\w\s*]*)/) {
+ $func = $1;
+ $flags = $2;
+
+ $xflags = $funcs->{$func};
+ if (1) {
+ if ($flags ne $xflags) {
+ print "$func: \"$flags\" should be \"$xflags\"\n";
+ }
+ } else {
+ print "FIXME: function \"$func\" has no disassembly\n";
+ $error = 1;
+ }
+ } else {
+ print "FIXME: bad match: $_\n";
+ }
+}
+
+exit $error;
+
+
diff --git a/testsuite/instruction/list-impls.c b/testsuite/instruction/list-impls.c
new file mode 100644
index 0000000..905f64b
--- /dev/null
+++ b/testsuite/instruction/list-impls.c
@@ -0,0 +1,83 @@
+/*
+ * LIBOIL - Library of Optimized Inner Loops
+ * Copyright (c) 2004 David A. Schleef <ds@schleef.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <liboil/liboil.h>
+#include <liboil/liboilfunction.h>
+#include <liboil/liboilcpu.h>
+#include <liboil/liboiltest.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdarg.h>
+
+int
+main (int argc, char *argv[])
+{
+ int n;
+ int i;
+
+ oil_init();
+
+ n = oil_class_get_n_classes ();
+ for (i = 0; i < n; i++){
+ OilFunctionClass *klass = oil_class_get_by_index (i);
+ OilFunctionImpl *impl;
+
+ for (impl = klass->first_impl; impl; impl = impl->next) {
+ printf("%s:", impl->name);
+#ifdef HAVE_CPU_I386
+ if (impl->flags & OIL_IMPL_FLAG_3DNOW)
+ printf(" 3dnow");
+ if (impl->flags & OIL_IMPL_FLAG_3DNOWEXT)
+ printf(" 3dnowext");
+ if (impl->flags & OIL_IMPL_FLAG_CMOV)
+ printf(" cmov");
+ if (impl->flags & OIL_IMPL_FLAG_MMX)
+ printf(" mmx");
+ if (impl->flags & OIL_IMPL_FLAG_MMXEXT)
+ printf(" mmxext");
+ if (impl->flags & OIL_IMPL_FLAG_SSE)
+ printf(" sse");
+ if (impl->flags & OIL_IMPL_FLAG_SSE2)
+ printf(" sse2");
+#endif
+#ifdef HAVE_CPU_PPC
+ if (impl->flags & OIL_IMPL_FLAG_ALTIVEC)
+ printf(" altivec");
+#endif
+ printf("\n");
+ }
+ }
+
+ return 0;
+}
+