--- /dev/null
+//**************************************************************************
+// Double-precision general matrix multiplication benchmark
+//--------------------------------------------------------------------------
+
+//--------------------------------------------------------------------------
+// Macros
+
+// Set HOST_DEBUG to 1 if you are going to compile this for a host
+// machine (ie Athena/Linux) for debug purposes and set HOST_DEBUG
+// to 0 if you are compiling with the smips-gcc toolchain.
+
+#ifndef HOST_DEBUG
+#define HOST_DEBUG 0
+#endif
+
+// Set PREALLOCATE to 1 if you want to preallocate the benchmark
+// function before starting stats. If you have instruction/data
+// caches and you don't want to count the overhead of misses, then
+// you will need to use preallocation.
+
+#ifndef PREALLOCATE
+#define PREALLOCATE 0
+#endif
+
+// Set SET_STATS to 1 if you want to carve out the piece that actually
+// does the computation.
+
+#ifndef SET_STATS
+#define SET_STATS 0
+#endif
+
+//--------------------------------------------------------------------------
+// Input/Reference Data
+
+#include "dataset1.h"
+
+//--------------------------------------------------------------------------
+// Helper functions
+
+int verify( long n, const double test[], const double correct[] )
+{
+ int i;
+ for ( i = 0; i < n; i++ ) {
+ if ( test[i] != correct[i] ) {
+ return 2;
+ }
+ }
+ return 1;
+}
+
+#if HOST_DEBUG
+#include <stdio.h>
+#include <stdlib.h>
+void printArray( char name[], long n, const double arr[] )
+{
+ int i;
+ printf( " %10s :", name );
+ for ( i = 0; i < n; i++ )
+ printf( " %8.1f ", arr[i] );
+ printf( "\n" );
+}
+#endif
+
+void finishTest( int toHostValue )
+{
+#if HOST_DEBUG
+ if ( toHostValue == 1 )
+ printf( "*** PASSED ***\n" );
+ else
+ printf( "*** FAILED *** (tohost = %d)\n", toHostValue );
+ exit(0);
+#else
+ asm( "mtpcr %0, cr30" : : "r" (toHostValue) );
+ while ( 1 ) { }
+#endif
+}
+
+void setStats( int enable )
+{
+#if ( !HOST_DEBUG && SET_STATS )
+ asm( "mtpcr %0, cr10" : : "r" (enable) );
+#endif
+}
+
+void spmv(int r, const double* val, const int* idx, const double* x,
+ const int* ptr, double* y)
+{
+ for (int i = 0; i < r; i++)
+ {
+ int k;
+ double yi0 = 0, yi1 = 0, yi2 = 0, yi3 = 0;
+ for (k = ptr[i]; k < ptr[i+1]-3; k+=4)
+ {
+ yi0 += val[k+0]*x[idx[k+0]];
+ yi1 += val[k+1]*x[idx[k+1]];
+ yi2 += val[k+2]*x[idx[k+2]];
+ yi3 += val[k+3]*x[idx[k+3]];
+ }
+ for ( ; k < ptr[i+1]; k++)
+ {
+ yi0 += val[k]*x[idx[k]];
+ }
+ y[i] = (yi0+yi1)+(yi2+yi3);
+ }
+}
+
+//--------------------------------------------------------------------------
+// Main
+
+int main( int argc, char* argv[] )
+{
+ double y[R];
+
+#if PREALLOCATE
+ spmv(R, val, idx, x, ptr, y);
+#endif
+
+ setStats(1);
+ spmv(R, val, idx, x, ptr, y);
+ setStats(0);
+
+ finishTest(verify(R, y, verify_data));
+}