summaryrefslogtreecommitdiff
path: root/testsuite/mmx_engine.c
diff options
context:
space:
mode:
authorDavid Schleef <ds@schleef.org>2006-01-31 02:20:03 +0000
committerDavid Schleef <ds@schleef.org>2006-01-31 02:20:03 +0000
commit056a04b9f623a60d01c50581a567501833e40221 (patch)
tree2d7af5e042d6916642da072b4ed9e825cd38d2b4 /testsuite/mmx_engine.c
parent3f3a246341c1b5ac1c19257e871d1a2c977cdf61 (diff)
downloadliboil-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.c221
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
+