diff options
author | David Schleef <ds@schleef.org> | 2005-06-16 06:46:06 +0000 |
---|---|---|
committer | David Schleef <ds@schleef.org> | 2005-06-16 06:46:06 +0000 |
commit | 508ba3985f38081917b76fcfc4ac84e73ca2954a (patch) | |
tree | bd56b3f8c781a82c6f018a6d4a03d2c33fdd7a5b /testsuite | |
parent | 7ffccb74ac2ebfd0b6f8361d4016b0ceb3c9581f (diff) | |
download | liboil-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.am | 2 | ||||
-rw-r--r-- | testsuite/instruction/Makefile.am | 15 | ||||
-rwxr-xr-x | testsuite/instruction/check-instructions.pl | 444 | ||||
-rw-r--r-- | testsuite/instruction/list-impls.c | 83 |
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; +} + |