diff options
author | David Schleef <ds@schleef.org> | 2006-01-31 02:20:03 +0000 |
---|---|---|
committer | David Schleef <ds@schleef.org> | 2006-01-31 02:20:03 +0000 |
commit | 056a04b9f623a60d01c50581a567501833e40221 (patch) | |
tree | 2d7af5e042d6916642da072b4ed9e825cd38d2b4 /testsuite/mmx_engine.c | |
parent | 3f3a246341c1b5ac1c19257e871d1a2c977cdf61 (diff) | |
download | liboil-056a04b9f623a60d01c50581a567501833e40221.tar.gz |
* configure.ac:
* m4/as-host-defines.m4:
* liboil/Makefile.am:
* liboil/motovec/Makefile.am:
* doc/liboil-sections.txt:
* doc/tmpl/liboil-unused.sgml:
* doc/tmpl/liboilimpl-unstable.sgml:
* examples/oil-inspect.c:
* testsuite/instruction/Makefile.am:
Rewrite macros/defines for cpu selection. HAVE_${arch} is
the define for cpu architecture, HAVE_GCC_ASM is the define
for GCC inline assembly.
* liboil/liboilfunction.h:
Make implementation flags all part of the same enum, making
flags unique across all architectures. This makes it easier
to turn flags into feature names platform-independently.
* liboil/liboilclasses.h: update
* liboil/liboilfuncs-04.h:
* liboil/liboilfuncs.h:
* liboil/liboiltrampolines.c:
* liboil/liboilrandom.c: Fix documentation.
* liboil/liboiltest.c: same
* liboil/liboilrandom.h: remove config.h
* license_block: new year
* COPYING: Add copyright for mt19937
* examples/Makefile.am:
* examples/oil-mt19937.c:
* liboil/ref/Makefile.am:
* liboil/ref/mt19937ar.c:
* liboil/i386/Makefile.am:
* liboil/i386/mt19937.c:
Add mt19937 and example.
* testsuite/Makefile.am:
* testsuite/mmx_engine.c:
A little thingy for testing the features of an MMX engine.
Diffstat (limited to 'testsuite/mmx_engine.c')
-rw-r--r-- | testsuite/mmx_engine.c | 221 |
1 files changed, 221 insertions, 0 deletions
diff --git a/testsuite/mmx_engine.c b/testsuite/mmx_engine.c new file mode 100644 index 0000000..fa7e7c4 --- /dev/null +++ b/testsuite/mmx_engine.c @@ -0,0 +1,221 @@ +/* + * LIBOIL - Library of Optimized Inner Loops + * Copyright (c) 2006 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 <stdio.h> +#include <liboil/liboil.h> + +#include <liboil/liboilprototype.h> +#include <liboil/liboiltest.h> +#include <liboil/liboilcpu.h> +#include <liboil/liboilrandom.h> + +void mmx_engine_test(void); + +int main (int argc, char *argv[]) +{ + uint32_t cpu_flags; + + oil_init (); + + cpu_flags = oil_cpu_get_flags (); + if (!(cpu_flags & OIL_IMPL_FLAG_MMX)) { + printf("No MMX.\n"); + exit(0); + } + +#ifdef HAVE_GCC_ASM +#if defined(HAVE_I386) || defined(HAVE_AMD64) + mmx_engine_test(); +#endif +#endif + + return 0; +} + +#ifdef HAVE_GCC_ASM +#if defined(HAVE_I386) || defined(HAVE_AMD64) +void mmx_engine_test(void) +{ + OilProfile prof; + double ave, std; + int i; + +#define CHECK_LATENCY(insn) \ + oil_profile_init (&prof); \ + for(i=0;i<10;i++) { \ + oil_profile_start(&prof); \ + asm volatile ( \ + " mov $1000, %%ecx\n" \ + ".align 16\n" \ + "1:\n" \ + " " #insn " %%mm0, %%mm1\n" \ + " " #insn " %%mm1, %%mm2\n" \ + " " #insn " %%mm2, %%mm3\n" \ + " " #insn " %%mm3, %%mm0\n" \ + " decl %%ecx\n" \ + " jne 1b\n" \ + " emms\n" \ + :::"ecx"); \ + oil_profile_stop(&prof); \ + } \ + oil_profile_get_ave_std(&prof, &ave, &std); \ + ave -= 40; \ + printf("latency of " #insn ": %g +/- %g\n", ave/4000, std/4000); \ + + CHECK_LATENCY(packssdw) + CHECK_LATENCY(packsswb) + CHECK_LATENCY(packuswb) + CHECK_LATENCY(paddb) + CHECK_LATENCY(paddd) + CHECK_LATENCY(paddsb) + CHECK_LATENCY(paddsw) + CHECK_LATENCY(paddusb) + CHECK_LATENCY(paddusw) + CHECK_LATENCY(paddw) + CHECK_LATENCY(pand) + CHECK_LATENCY(pandn) + CHECK_LATENCY(pcmpeqb) + CHECK_LATENCY(pcmpeqd) + CHECK_LATENCY(pcmpeqw) + CHECK_LATENCY(pcmpgtb) + CHECK_LATENCY(pcmpgtd) + CHECK_LATENCY(pcmpgtw) + CHECK_LATENCY(pmaddwd) + CHECK_LATENCY(pmulhw) + CHECK_LATENCY(pmullw) + CHECK_LATENCY(pmulhuw) + CHECK_LATENCY(por) + CHECK_LATENCY(pslld) + CHECK_LATENCY(psllq) + CHECK_LATENCY(psllw) + CHECK_LATENCY(psrad) + CHECK_LATENCY(psraw) + CHECK_LATENCY(psrld) + CHECK_LATENCY(psrlq) + CHECK_LATENCY(psrlw) + CHECK_LATENCY(psubb) + CHECK_LATENCY(psubd) + CHECK_LATENCY(psubsb) + CHECK_LATENCY(psubsw) + CHECK_LATENCY(psubusb) + CHECK_LATENCY(psubusw) + CHECK_LATENCY(psubw) + CHECK_LATENCY(punpckhbw) + CHECK_LATENCY(punpckhdq) + CHECK_LATENCY(punpckhwd) + CHECK_LATENCY(punpcklbw) + CHECK_LATENCY(punpckldq) + CHECK_LATENCY(punpcklwd) + CHECK_LATENCY(pxor) + +#define CHECK_THROUGHPUT(insn) \ + oil_profile_init (&prof); \ + for(i=0;i<10;i++) { \ + oil_profile_start(&prof); \ + asm volatile ( \ + " mov $1000, %%ecx\n" \ + ".align 16\n" \ + "1:\n" \ + " " #insn " %%mm0, %%mm1\n" \ + " " #insn " %%mm2, %%mm3\n" \ + " " #insn " %%mm4, %%mm5\n" \ + " " #insn " %%mm6, %%mm7\n" \ + " " #insn " %%mm0, %%mm1\n" \ + " " #insn " %%mm2, %%mm3\n" \ + " " #insn " %%mm4, %%mm5\n" \ + " " #insn " %%mm6, %%mm7\n" \ + " " #insn " %%mm0, %%mm1\n" \ + " " #insn " %%mm2, %%mm3\n" \ + " " #insn " %%mm4, %%mm5\n" \ + " " #insn " %%mm6, %%mm7\n" \ + " " #insn " %%mm0, %%mm1\n" \ + " " #insn " %%mm2, %%mm3\n" \ + " " #insn " %%mm4, %%mm5\n" \ + " " #insn " %%mm6, %%mm7\n" \ + " decl %%ecx\n" \ + " jne 1b\n" \ + " emms\n" \ + :::"ecx"); \ + oil_profile_stop(&prof); \ + } \ + oil_profile_get_ave_std(&prof, &ave, &std); \ + ave -= 40; \ + printf("throughput of " #insn ": %g +/- %g\n", ave/16000, std/16000); \ + + CHECK_THROUGHPUT(packssdw) + CHECK_THROUGHPUT(packsswb) + CHECK_THROUGHPUT(packuswb) + CHECK_THROUGHPUT(paddb) + CHECK_THROUGHPUT(paddd) + CHECK_THROUGHPUT(paddsb) + CHECK_THROUGHPUT(paddsw) + CHECK_THROUGHPUT(paddusb) + CHECK_THROUGHPUT(paddusw) + CHECK_THROUGHPUT(paddw) + CHECK_THROUGHPUT(pand) + CHECK_THROUGHPUT(pandn) + CHECK_THROUGHPUT(pcmpeqb) + CHECK_THROUGHPUT(pcmpeqd) + CHECK_THROUGHPUT(pcmpeqw) + CHECK_THROUGHPUT(pcmpgtb) + CHECK_THROUGHPUT(pcmpgtd) + CHECK_THROUGHPUT(pcmpgtw) + CHECK_THROUGHPUT(pmaddwd) + CHECK_THROUGHPUT(pmulhw) + CHECK_THROUGHPUT(pmullw) + CHECK_THROUGHPUT(pmulhuw) + CHECK_THROUGHPUT(por) + CHECK_THROUGHPUT(pslld) + CHECK_THROUGHPUT(psllq) + CHECK_THROUGHPUT(psllw) + CHECK_THROUGHPUT(psrad) + CHECK_THROUGHPUT(psraw) + CHECK_THROUGHPUT(psrld) + CHECK_THROUGHPUT(psrlq) + CHECK_THROUGHPUT(psrlw) + CHECK_THROUGHPUT(psubb) + CHECK_THROUGHPUT(psubd) + CHECK_THROUGHPUT(psubsb) + CHECK_THROUGHPUT(psubsw) + CHECK_THROUGHPUT(psubusb) + CHECK_THROUGHPUT(psubusw) + CHECK_THROUGHPUT(psubw) + CHECK_THROUGHPUT(punpckhbw) + CHECK_THROUGHPUT(punpckhdq) + CHECK_THROUGHPUT(punpckhwd) + CHECK_THROUGHPUT(punpcklbw) + CHECK_THROUGHPUT(punpckldq) + CHECK_THROUGHPUT(punpcklwd) + CHECK_THROUGHPUT(pxor) +} +#endif +#endif + |