summaryrefslogtreecommitdiff
path: root/testsuite/mmx_engine.c
diff options
context:
space:
mode:
authorDavid Schleef <ds@schleef.org>2006-01-31 03:19:35 +0000
committerDavid Schleef <ds@schleef.org>2006-01-31 03:19:35 +0000
commitd14fb56ab84532957842d95dba6e41de2be1cc80 (patch)
treee5d26094d7aef0e0c5dcd5f5d6d8d0e7a7f89bad /testsuite/mmx_engine.c
parent056a04b9f623a60d01c50581a567501833e40221 (diff)
downloadliboil-d14fb56ab84532957842d95dba6e41de2be1cc80.tar.gz
* testsuite/mmx_engine.c: Add SSE2
Diffstat (limited to 'testsuite/mmx_engine.c')
-rw-r--r--testsuite/mmx_engine.c246
1 files changed, 225 insertions, 21 deletions
diff --git a/testsuite/mmx_engine.c b/testsuite/mmx_engine.c
index fa7e7c4..a22217a 100644
--- a/testsuite/mmx_engine.c
+++ b/testsuite/mmx_engine.c
@@ -30,6 +30,7 @@
#endif
#include <stdio.h>
+#include <math.h>
#include <liboil/liboil.h>
#include <liboil/liboilprototype.h>
@@ -37,7 +38,10 @@
#include <liboil/liboilcpu.h>
#include <liboil/liboilrandom.h>
+#define OFFSET 100
+
void mmx_engine_test(void);
+void sse2_engine_test(void);
int main (int argc, char *argv[])
{
@@ -46,26 +50,66 @@ int main (int argc, char *argv[])
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();
+ if (cpu_flags & OIL_IMPL_FLAG_MMX) {
+ mmx_engine_test();
+ } else {
+ printf("No MMX.\n");
+ }
+ if (cpu_flags & OIL_IMPL_FLAG_SSE2) {
+ sse2_engine_test();
+ } else {
+ printf("No SSE2.\n");
+ }
#endif
#endif
return 0;
}
+int sci_sprint_alt(char *s,double x,double y)
+{
+ int errsig;
+ int maxsig;
+ int sigfigs;
+ double mantissa;
+ double error;
+ double mindigit;
+
+ errsig = floor(log10(fabs(y)));
+ maxsig = floor(log10(fabs(x)));
+ mindigit = pow(10,errsig);
+
+ if(maxsig<errsig)maxsig=errsig;
+
+ sigfigs = maxsig-errsig+2;
+
+ mantissa = x*pow(10,-maxsig);
+ error = y*pow(10,-errsig+1);
+
+ if(isnan(x)){
+ return sprintf(s,"%g",x);
+ }
+ if(errsig==1 && maxsig<4 && maxsig>1){
+ return sprintf(s,"%0.0f(%2.0f)",x,error);
+ }
+ if(maxsig<=0 && maxsig>=-2){
+ return sprintf(s,"%0.*f(%2.0f)",sigfigs-1-maxsig,
+ mantissa*pow(10,maxsig),error);
+ }
+ return sprintf(s,"%0.*f(%2.0f)e%d",sigfigs-1,mantissa,error,maxsig);
+}
+
+
#ifdef HAVE_GCC_ASM
#if defined(HAVE_I386) || defined(HAVE_AMD64)
void mmx_engine_test(void)
{
OilProfile prof;
double ave, std;
+ char s[40];
int i;
#define CHECK_LATENCY(insn) \
@@ -87,8 +131,9 @@ void mmx_engine_test(void)
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); \
+ ave -= OFFSET; \
+ sci_sprint_alt(s,ave/4000,std/4000); \
+ printf("latency of " #insn ": %s\n", s);
CHECK_LATENCY(packssdw)
CHECK_LATENCY(packsswb)
@@ -145,21 +190,21 @@ void mmx_engine_test(void)
".align 16\n" \
"1:\n" \
" " #insn " %%mm0, %%mm1\n" \
- " " #insn " %%mm2, %%mm3\n" \
- " " #insn " %%mm4, %%mm5\n" \
- " " #insn " %%mm6, %%mm7\n" \
+ " " #insn " %%mm0, %%mm2\n" \
+ " " #insn " %%mm0, %%mm3\n" \
+ " " #insn " %%mm0, %%mm4\n" \
" " #insn " %%mm0, %%mm1\n" \
- " " #insn " %%mm2, %%mm3\n" \
- " " #insn " %%mm4, %%mm5\n" \
- " " #insn " %%mm6, %%mm7\n" \
+ " " #insn " %%mm0, %%mm2\n" \
+ " " #insn " %%mm0, %%mm3\n" \
+ " " #insn " %%mm0, %%mm4\n" \
" " #insn " %%mm0, %%mm1\n" \
- " " #insn " %%mm2, %%mm3\n" \
- " " #insn " %%mm4, %%mm5\n" \
- " " #insn " %%mm6, %%mm7\n" \
+ " " #insn " %%mm0, %%mm2\n" \
+ " " #insn " %%mm0, %%mm3\n" \
+ " " #insn " %%mm0, %%mm4\n" \
" " #insn " %%mm0, %%mm1\n" \
- " " #insn " %%mm2, %%mm3\n" \
- " " #insn " %%mm4, %%mm5\n" \
- " " #insn " %%mm6, %%mm7\n" \
+ " " #insn " %%mm0, %%mm2\n" \
+ " " #insn " %%mm0, %%mm3\n" \
+ " " #insn " %%mm0, %%mm4\n" \
" decl %%ecx\n" \
" jne 1b\n" \
" emms\n" \
@@ -167,8 +212,166 @@ void mmx_engine_test(void)
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); \
+ ave -= OFFSET; \
+ sci_sprint_alt(s,ave/16000,std/16000); \
+ printf("throughput of " #insn ": %s\n", s);
+
+ 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)
+
+#undef CHECK_LATENCY
+#undef CHECK_THROUGHPUT
+}
+
+void sse2_engine_test(void)
+{
+ OilProfile prof;
+ double ave, std;
+ char s[40];
+ 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 " %%xmm0, %%xmm1\n" \
+ " " #insn " %%xmm1, %%xmm2\n" \
+ " " #insn " %%xmm2, %%xmm3\n" \
+ " " #insn " %%xmm3, %%xmm0\n" \
+ " decl %%ecx\n" \
+ " jne 1b\n" \
+ :::"ecx"); \
+ oil_profile_stop(&prof); \
+ } \
+ oil_profile_get_ave_std(&prof, &ave, &std); \
+ ave -= OFFSET; \
+ sci_sprint_alt(s,ave/4000,std/4000); \
+ printf("latency of " #insn ": %s\n", s);
+
+ 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 " %%xmm0, %%xmm1\n" \
+ " " #insn " %%xmm0, %%xmm2\n" \
+ " " #insn " %%xmm0, %%xmm3\n" \
+ " " #insn " %%xmm0, %%xmm4\n" \
+ " " #insn " %%xmm0, %%xmm5\n" \
+ " " #insn " %%xmm0, %%xmm6\n" \
+ " " #insn " %%xmm0, %%xmm7\n" \
+ " " #insn " %%xmm0, %%xmm1\n" \
+ " " #insn " %%xmm0, %%xmm2\n" \
+ " " #insn " %%xmm0, %%xmm3\n" \
+ " " #insn " %%xmm0, %%xmm4\n" \
+ " " #insn " %%xmm0, %%xmm5\n" \
+ " " #insn " %%xmm0, %%xmm6\n" \
+ " " #insn " %%xmm0, %%xmm7\n" \
+ " decl %%ecx\n" \
+ " jne 1b\n" \
+ :::"ecx"); \
+ oil_profile_stop(&prof); \
+ } \
+ oil_profile_get_ave_std(&prof, &ave, &std); \
+ ave -= OFFSET; \
+ sci_sprint_alt(s,ave/14000,std/14000); \
+ printf("throughput of " #insn ": %s\n", s);
CHECK_THROUGHPUT(packssdw)
CHECK_THROUGHPUT(packsswb)
@@ -219,3 +422,4 @@ void mmx_engine_test(void)
#endif
#endif
+