see http://mbed.org/users/no2chem/notebook/mbed-clock-control--benchmarks/

Dependencies:   mbed

Committer:
no2chem
Date:
Sun Jan 24 15:46:26 2010 +0000
Revision:
0:b5d3bd64d2dc

        

Who changed what in which revision?

UserRevisionLine numberNew contents of line
no2chem 0:b5d3bd64d2dc 1 /*
no2chem 0:b5d3bd64d2dc 2 Author : Shay Gal-On, EEMBC
no2chem 0:b5d3bd64d2dc 3
no2chem 0:b5d3bd64d2dc 4 This file is part of EEMBC(R) and CoreMark(TM), which are Copyright (C) 2009
no2chem 0:b5d3bd64d2dc 5 All rights reserved.
no2chem 0:b5d3bd64d2dc 6
no2chem 0:b5d3bd64d2dc 7 EEMBC CoreMark Software is a product of EEMBC and is provided under the terms of the
no2chem 0:b5d3bd64d2dc 8 CoreMark License that is distributed with the official EEMBC COREMARK Software release.
no2chem 0:b5d3bd64d2dc 9 If you received this EEMBC CoreMark Software without the accompanying CoreMark License,
no2chem 0:b5d3bd64d2dc 10 you must discontinue use and download the official release from www.coremark.org.
no2chem 0:b5d3bd64d2dc 11
no2chem 0:b5d3bd64d2dc 12 Also, if you are publicly displaying scores generated from the EEMBC CoreMark software,
no2chem 0:b5d3bd64d2dc 13 make sure that you are in compliance with Run and Reporting rules specified in the accompanying readme.txt file.
no2chem 0:b5d3bd64d2dc 14
no2chem 0:b5d3bd64d2dc 15 EEMBC
no2chem 0:b5d3bd64d2dc 16 4354 Town Center Blvd. Suite 114-200
no2chem 0:b5d3bd64d2dc 17 El Dorado Hills, CA, 95762
no2chem 0:b5d3bd64d2dc 18 */
no2chem 0:b5d3bd64d2dc 19 #include "coremark.h"
no2chem 0:b5d3bd64d2dc 20 /*
no2chem 0:b5d3bd64d2dc 21 Topic: Description
no2chem 0:b5d3bd64d2dc 22 Matrix manipulation benchmark
no2chem 0:b5d3bd64d2dc 23
no2chem 0:b5d3bd64d2dc 24 This very simple algorithm forms the basis of many more complex algorithms.
no2chem 0:b5d3bd64d2dc 25
no2chem 0:b5d3bd64d2dc 26 The tight inner loop is the focus of many optimizations (compiler as well as hardware based)
no2chem 0:b5d3bd64d2dc 27 and is thus relevant for embedded processing.
no2chem 0:b5d3bd64d2dc 28
no2chem 0:b5d3bd64d2dc 29 The total available data space will be divided to 3 parts:
no2chem 0:b5d3bd64d2dc 30 NxN Matrix A - initialized with small values (upper 3/4 of the bits all zero).
no2chem 0:b5d3bd64d2dc 31 NxN Matrix B - initialized with medium values (upper half of the bits all zero).
no2chem 0:b5d3bd64d2dc 32 NxN Matrix C - used for the result.
no2chem 0:b5d3bd64d2dc 33
no2chem 0:b5d3bd64d2dc 34 The actual values for A and B must be derived based on input that is not available at compile time.
no2chem 0:b5d3bd64d2dc 35 */
no2chem 0:b5d3bd64d2dc 36 ee_s16 matrix_test(ee_u32 N, MATRES *C, MATDAT *A, MATDAT *B, MATDAT val);
no2chem 0:b5d3bd64d2dc 37 ee_s16 matrix_sum(ee_u32 N, MATRES *C, MATDAT clipval);
no2chem 0:b5d3bd64d2dc 38 void matrix_mul_const(ee_u32 N, MATRES *C, MATDAT *A, MATDAT val);
no2chem 0:b5d3bd64d2dc 39 void matrix_mul_vect(ee_u32 N, MATRES *C, MATDAT *A, MATDAT *B);
no2chem 0:b5d3bd64d2dc 40 void matrix_mul_matrix(ee_u32 N, MATRES *C, MATDAT *A, MATDAT *B);
no2chem 0:b5d3bd64d2dc 41 void matrix_mul_matrix_bitextract(ee_u32 N, MATRES *C, MATDAT *A, MATDAT *B);
no2chem 0:b5d3bd64d2dc 42 void matrix_add_const(ee_u32 N, MATDAT *A, MATDAT val);
no2chem 0:b5d3bd64d2dc 43
no2chem 0:b5d3bd64d2dc 44 #define matrix_test_next(x) (x+1)
no2chem 0:b5d3bd64d2dc 45 #define matrix_clip(x,y) ((y) ? (x) & 0x0ff : (x) & 0x0ffff)
no2chem 0:b5d3bd64d2dc 46 #define matrix_big(x) (0xf000 | (x))
no2chem 0:b5d3bd64d2dc 47 #define bit_extract(x,from,to) (((x)>>(from)) & (~(0xffffffff << (to))))
no2chem 0:b5d3bd64d2dc 48
no2chem 0:b5d3bd64d2dc 49 #if CORE_DEBUG
no2chem 0:b5d3bd64d2dc 50 void printmat(MATDAT *A, ee_u32 N, char *name) {
no2chem 0:b5d3bd64d2dc 51 ee_u32 i,j;
no2chem 0:b5d3bd64d2dc 52 ee_printf("Matrix %s [%dx%d]:\n",name,N,N);
no2chem 0:b5d3bd64d2dc 53 for (i=0; i<N; i++) {
no2chem 0:b5d3bd64d2dc 54 for (j=0; j<N; j++) {
no2chem 0:b5d3bd64d2dc 55 if (j!=0)
no2chem 0:b5d3bd64d2dc 56 ee_printf(",");
no2chem 0:b5d3bd64d2dc 57 ee_printf("%d",A[i*N+j]);
no2chem 0:b5d3bd64d2dc 58 }
no2chem 0:b5d3bd64d2dc 59 ee_printf("\n");
no2chem 0:b5d3bd64d2dc 60 }
no2chem 0:b5d3bd64d2dc 61 }
no2chem 0:b5d3bd64d2dc 62 void printmatC(MATRES *C, ee_u32 N, char *name) {
no2chem 0:b5d3bd64d2dc 63 ee_u32 i,j;
no2chem 0:b5d3bd64d2dc 64 ee_printf("Matrix %s [%dx%d]:\n",name,N,N);
no2chem 0:b5d3bd64d2dc 65 for (i=0; i<N; i++) {
no2chem 0:b5d3bd64d2dc 66 for (j=0; j<N; j++) {
no2chem 0:b5d3bd64d2dc 67 if (j!=0)
no2chem 0:b5d3bd64d2dc 68 ee_printf(",");
no2chem 0:b5d3bd64d2dc 69 ee_printf("%d",C[i*N+j]);
no2chem 0:b5d3bd64d2dc 70 }
no2chem 0:b5d3bd64d2dc 71 ee_printf("\n");
no2chem 0:b5d3bd64d2dc 72 }
no2chem 0:b5d3bd64d2dc 73 }
no2chem 0:b5d3bd64d2dc 74 #endif
no2chem 0:b5d3bd64d2dc 75 /* Function: core_bench_matrix
no2chem 0:b5d3bd64d2dc 76 Benchmark function
no2chem 0:b5d3bd64d2dc 77
no2chem 0:b5d3bd64d2dc 78 Iterate <matrix_test> N times,
no2chem 0:b5d3bd64d2dc 79 changing the matrix values slightly by a constant amount each time.
no2chem 0:b5d3bd64d2dc 80 */
no2chem 0:b5d3bd64d2dc 81 ee_u16 core_bench_matrix(mat_params *p, ee_s16 seed, ee_u16 crc) {
no2chem 0:b5d3bd64d2dc 82 ee_u32 N=p->N;
no2chem 0:b5d3bd64d2dc 83 MATRES *C=p->C;
no2chem 0:b5d3bd64d2dc 84 MATDAT *A=p->A;
no2chem 0:b5d3bd64d2dc 85 MATDAT *B=p->B;
no2chem 0:b5d3bd64d2dc 86 MATDAT val=(MATDAT)seed;
no2chem 0:b5d3bd64d2dc 87
no2chem 0:b5d3bd64d2dc 88 crc=crc16(matrix_test(N,C,A,B,val),crc);
no2chem 0:b5d3bd64d2dc 89
no2chem 0:b5d3bd64d2dc 90 return crc;
no2chem 0:b5d3bd64d2dc 91 }
no2chem 0:b5d3bd64d2dc 92
no2chem 0:b5d3bd64d2dc 93 /* Function: matrix_test
no2chem 0:b5d3bd64d2dc 94 Perform matrix manipulation.
no2chem 0:b5d3bd64d2dc 95
no2chem 0:b5d3bd64d2dc 96 Parameters:
no2chem 0:b5d3bd64d2dc 97 N - Dimensions of the matrix.
no2chem 0:b5d3bd64d2dc 98 C - memory for result matrix.
no2chem 0:b5d3bd64d2dc 99 A - input matrix
no2chem 0:b5d3bd64d2dc 100 B - operator matrix (not changed during operations)
no2chem 0:b5d3bd64d2dc 101
no2chem 0:b5d3bd64d2dc 102 Returns:
no2chem 0:b5d3bd64d2dc 103 A CRC value that captures all results calculated in the function.
no2chem 0:b5d3bd64d2dc 104 In particular, crc of the value calculated on the result matrix
no2chem 0:b5d3bd64d2dc 105 after each step by <matrix_sum>.
no2chem 0:b5d3bd64d2dc 106
no2chem 0:b5d3bd64d2dc 107 Operation:
no2chem 0:b5d3bd64d2dc 108
no2chem 0:b5d3bd64d2dc 109 1 - Add a constant value to all elements of a matrix.
no2chem 0:b5d3bd64d2dc 110 2 - Multiply a matrix by a constant.
no2chem 0:b5d3bd64d2dc 111 3 - Multiply a matrix by a vector.
no2chem 0:b5d3bd64d2dc 112 4 - Multiply a matrix by a matrix.
no2chem 0:b5d3bd64d2dc 113 5 - Add a constant value to all elements of a matrix.
no2chem 0:b5d3bd64d2dc 114
no2chem 0:b5d3bd64d2dc 115 After the last step, matrix A is back to original contents.
no2chem 0:b5d3bd64d2dc 116 */
no2chem 0:b5d3bd64d2dc 117 ee_s16 matrix_test(ee_u32 N, MATRES *C, MATDAT *A, MATDAT *B, MATDAT val) {
no2chem 0:b5d3bd64d2dc 118 ee_u16 crc=0;
no2chem 0:b5d3bd64d2dc 119 MATDAT clipval=matrix_big(val);
no2chem 0:b5d3bd64d2dc 120
no2chem 0:b5d3bd64d2dc 121 matrix_add_const(N,A,val); /* make sure data changes */
no2chem 0:b5d3bd64d2dc 122 #if CORE_DEBUG
no2chem 0:b5d3bd64d2dc 123 printmat(A,N,"matrix_add_const");
no2chem 0:b5d3bd64d2dc 124 #endif
no2chem 0:b5d3bd64d2dc 125 matrix_mul_const(N,C,A,val);
no2chem 0:b5d3bd64d2dc 126 crc=crc16(matrix_sum(N,C,clipval),crc);
no2chem 0:b5d3bd64d2dc 127 #if CORE_DEBUG
no2chem 0:b5d3bd64d2dc 128 printmatC(C,N,"matrix_mul_const");
no2chem 0:b5d3bd64d2dc 129 #endif
no2chem 0:b5d3bd64d2dc 130 matrix_mul_vect(N,C,A,B);
no2chem 0:b5d3bd64d2dc 131 crc=crc16(matrix_sum(N,C,clipval),crc);
no2chem 0:b5d3bd64d2dc 132 #if CORE_DEBUG
no2chem 0:b5d3bd64d2dc 133 printmatC(C,N,"matrix_mul_vect");
no2chem 0:b5d3bd64d2dc 134 #endif
no2chem 0:b5d3bd64d2dc 135 matrix_mul_matrix(N,C,A,B);
no2chem 0:b5d3bd64d2dc 136 crc=crc16(matrix_sum(N,C,clipval),crc);
no2chem 0:b5d3bd64d2dc 137 #if CORE_DEBUG
no2chem 0:b5d3bd64d2dc 138 printmatC(C,N,"matrix_mul_matrix");
no2chem 0:b5d3bd64d2dc 139 #endif
no2chem 0:b5d3bd64d2dc 140 matrix_mul_matrix_bitextract(N,C,A,B);
no2chem 0:b5d3bd64d2dc 141 crc=crc16(matrix_sum(N,C,clipval),crc);
no2chem 0:b5d3bd64d2dc 142 #if CORE_DEBUG
no2chem 0:b5d3bd64d2dc 143 printmatC(C,N,"matrix_mul_matrix_bitextract");
no2chem 0:b5d3bd64d2dc 144 #endif
no2chem 0:b5d3bd64d2dc 145
no2chem 0:b5d3bd64d2dc 146 matrix_add_const(N,A,-val); /* return matrix to initial value */
no2chem 0:b5d3bd64d2dc 147 return crc;
no2chem 0:b5d3bd64d2dc 148 }
no2chem 0:b5d3bd64d2dc 149
no2chem 0:b5d3bd64d2dc 150 /* Function : matrix_init
no2chem 0:b5d3bd64d2dc 151 Initialize the memory block for matrix benchmarking.
no2chem 0:b5d3bd64d2dc 152
no2chem 0:b5d3bd64d2dc 153 Parameters:
no2chem 0:b5d3bd64d2dc 154 blksize - Size of memory to be initialized.
no2chem 0:b5d3bd64d2dc 155 memblk - Pointer to memory block.
no2chem 0:b5d3bd64d2dc 156 seed - Actual values chosen depend on the seed parameter.
no2chem 0:b5d3bd64d2dc 157 p - pointers to <mat_params> containing initialized matrixes.
no2chem 0:b5d3bd64d2dc 158
no2chem 0:b5d3bd64d2dc 159 Returns:
no2chem 0:b5d3bd64d2dc 160 Matrix dimensions.
no2chem 0:b5d3bd64d2dc 161
no2chem 0:b5d3bd64d2dc 162 Note:
no2chem 0:b5d3bd64d2dc 163 The seed parameter MUST be supplied from a source that cannot be determined at compile time
no2chem 0:b5d3bd64d2dc 164 */
no2chem 0:b5d3bd64d2dc 165 ee_u32 core_init_matrix(ee_u32 blksize, void *memblk, ee_s32 seed, mat_params *p) {
no2chem 0:b5d3bd64d2dc 166 ee_u32 N=0;
no2chem 0:b5d3bd64d2dc 167 MATDAT *A;
no2chem 0:b5d3bd64d2dc 168 MATDAT *B;
no2chem 0:b5d3bd64d2dc 169 ee_s32 order=1;
no2chem 0:b5d3bd64d2dc 170 MATDAT val;
no2chem 0:b5d3bd64d2dc 171 ee_u32 i=0,j=0;
no2chem 0:b5d3bd64d2dc 172 if (seed==0)
no2chem 0:b5d3bd64d2dc 173 seed=1;
no2chem 0:b5d3bd64d2dc 174 while (j<blksize) {
no2chem 0:b5d3bd64d2dc 175 i++;
no2chem 0:b5d3bd64d2dc 176 j=i*i*2*4;
no2chem 0:b5d3bd64d2dc 177 }
no2chem 0:b5d3bd64d2dc 178 N=i-1;
no2chem 0:b5d3bd64d2dc 179 A=(MATDAT *)align_mem(memblk);
no2chem 0:b5d3bd64d2dc 180 B=A+N*N;
no2chem 0:b5d3bd64d2dc 181
no2chem 0:b5d3bd64d2dc 182 for (i=0; i<N; i++) {
no2chem 0:b5d3bd64d2dc 183 for (j=0; j<N; j++) {
no2chem 0:b5d3bd64d2dc 184 seed = ( ( order * seed ) % 65536 );
no2chem 0:b5d3bd64d2dc 185 val = (seed + order);
no2chem 0:b5d3bd64d2dc 186 val=matrix_clip(val,0);
no2chem 0:b5d3bd64d2dc 187 B[i*N+j] = val;
no2chem 0:b5d3bd64d2dc 188 val = (val + order);
no2chem 0:b5d3bd64d2dc 189 val=matrix_clip(val,1);
no2chem 0:b5d3bd64d2dc 190 A[i*N+j] = val;
no2chem 0:b5d3bd64d2dc 191 order++;
no2chem 0:b5d3bd64d2dc 192 }
no2chem 0:b5d3bd64d2dc 193 }
no2chem 0:b5d3bd64d2dc 194
no2chem 0:b5d3bd64d2dc 195 p->A=A;
no2chem 0:b5d3bd64d2dc 196 p->B=B;
no2chem 0:b5d3bd64d2dc 197 p->C=(MATRES *)align_mem(B+N*N);
no2chem 0:b5d3bd64d2dc 198 p->N=N;
no2chem 0:b5d3bd64d2dc 199 #if CORE_DEBUG
no2chem 0:b5d3bd64d2dc 200 printmat(A,N,"A");
no2chem 0:b5d3bd64d2dc 201 printmat(B,N,"B");
no2chem 0:b5d3bd64d2dc 202 #endif
no2chem 0:b5d3bd64d2dc 203 return N;
no2chem 0:b5d3bd64d2dc 204 }
no2chem 0:b5d3bd64d2dc 205
no2chem 0:b5d3bd64d2dc 206 /* Function: matrix_sum
no2chem 0:b5d3bd64d2dc 207 Calculate a function that depends on the values of elements in the matrix.
no2chem 0:b5d3bd64d2dc 208
no2chem 0:b5d3bd64d2dc 209 For each element, accumulate into a temporary variable.
no2chem 0:b5d3bd64d2dc 210
no2chem 0:b5d3bd64d2dc 211 As long as this value is under the parameter clipval,
no2chem 0:b5d3bd64d2dc 212 add 1 to the result if the element is bigger then the previous.
no2chem 0:b5d3bd64d2dc 213
no2chem 0:b5d3bd64d2dc 214 Otherwise, reset the accumulator and add 10 to the result.
no2chem 0:b5d3bd64d2dc 215 */
no2chem 0:b5d3bd64d2dc 216 ee_s16 matrix_sum(ee_u32 N, MATRES *C, MATDAT clipval) {
no2chem 0:b5d3bd64d2dc 217 MATRES tmp=0,prev=0,cur=0;
no2chem 0:b5d3bd64d2dc 218 ee_s16 ret=0;
no2chem 0:b5d3bd64d2dc 219 ee_u32 i,j;
no2chem 0:b5d3bd64d2dc 220 for (i=0; i<N; i++) {
no2chem 0:b5d3bd64d2dc 221 for (j=0; j<N; j++) {
no2chem 0:b5d3bd64d2dc 222 cur=C[i*N+j];
no2chem 0:b5d3bd64d2dc 223 tmp+=cur;
no2chem 0:b5d3bd64d2dc 224 if (tmp>clipval) {
no2chem 0:b5d3bd64d2dc 225 ret+=10;
no2chem 0:b5d3bd64d2dc 226 tmp=0;
no2chem 0:b5d3bd64d2dc 227 } else {
no2chem 0:b5d3bd64d2dc 228 ret += (cur>prev) ? 1 : 0;
no2chem 0:b5d3bd64d2dc 229 }
no2chem 0:b5d3bd64d2dc 230 prev=cur;
no2chem 0:b5d3bd64d2dc 231 }
no2chem 0:b5d3bd64d2dc 232 }
no2chem 0:b5d3bd64d2dc 233 return ret;
no2chem 0:b5d3bd64d2dc 234 }
no2chem 0:b5d3bd64d2dc 235
no2chem 0:b5d3bd64d2dc 236 /* Function: matrix_mul_const
no2chem 0:b5d3bd64d2dc 237 Multiply a matrix by a constant.
no2chem 0:b5d3bd64d2dc 238 This could be used as a scaler for instance.
no2chem 0:b5d3bd64d2dc 239 */
no2chem 0:b5d3bd64d2dc 240 void matrix_mul_const(ee_u32 N, MATRES *C, MATDAT *A, MATDAT val) {
no2chem 0:b5d3bd64d2dc 241 ee_u32 i,j;
no2chem 0:b5d3bd64d2dc 242 for (i=0; i<N; i++) {
no2chem 0:b5d3bd64d2dc 243 for (j=0; j<N; j++) {
no2chem 0:b5d3bd64d2dc 244 C[i*N+j]=(MATRES)A[i*N+j] * (MATRES)val;
no2chem 0:b5d3bd64d2dc 245 }
no2chem 0:b5d3bd64d2dc 246 }
no2chem 0:b5d3bd64d2dc 247 }
no2chem 0:b5d3bd64d2dc 248
no2chem 0:b5d3bd64d2dc 249 /* Function: matrix_add_const
no2chem 0:b5d3bd64d2dc 250 Add a constant value to all elements of a matrix.
no2chem 0:b5d3bd64d2dc 251 */
no2chem 0:b5d3bd64d2dc 252 void matrix_add_const(ee_u32 N, MATDAT *A, MATDAT val) {
no2chem 0:b5d3bd64d2dc 253 ee_u32 i,j;
no2chem 0:b5d3bd64d2dc 254 for (i=0; i<N; i++) {
no2chem 0:b5d3bd64d2dc 255 for (j=0; j<N; j++) {
no2chem 0:b5d3bd64d2dc 256 A[i*N+j] += val;
no2chem 0:b5d3bd64d2dc 257 }
no2chem 0:b5d3bd64d2dc 258 }
no2chem 0:b5d3bd64d2dc 259 }
no2chem 0:b5d3bd64d2dc 260
no2chem 0:b5d3bd64d2dc 261 /* Function: matrix_mul_vect
no2chem 0:b5d3bd64d2dc 262 Multiply a matrix by a vector.
no2chem 0:b5d3bd64d2dc 263 This is common in many simple filters (e.g. fir where a vector of coefficients is applied to the matrix.)
no2chem 0:b5d3bd64d2dc 264 */
no2chem 0:b5d3bd64d2dc 265 void matrix_mul_vect(ee_u32 N, MATRES *C, MATDAT *A, MATDAT *B) {
no2chem 0:b5d3bd64d2dc 266 ee_u32 i,j;
no2chem 0:b5d3bd64d2dc 267 for (i=0; i<N; i++) {
no2chem 0:b5d3bd64d2dc 268 C[i]=0;
no2chem 0:b5d3bd64d2dc 269 for (j=0; j<N; j++) {
no2chem 0:b5d3bd64d2dc 270 C[i]+=(MATRES)A[i*N+j] * (MATRES)B[j];
no2chem 0:b5d3bd64d2dc 271 }
no2chem 0:b5d3bd64d2dc 272 }
no2chem 0:b5d3bd64d2dc 273 }
no2chem 0:b5d3bd64d2dc 274
no2chem 0:b5d3bd64d2dc 275 /* Function: matrix_mul_matrix
no2chem 0:b5d3bd64d2dc 276 Multiply a matrix by a matrix.
no2chem 0:b5d3bd64d2dc 277 Basic code is used in many algorithms, mostly with minor changes such as scaling.
no2chem 0:b5d3bd64d2dc 278 */
no2chem 0:b5d3bd64d2dc 279 void matrix_mul_matrix(ee_u32 N, MATRES *C, MATDAT *A, MATDAT *B) {
no2chem 0:b5d3bd64d2dc 280 ee_u32 i,j,k;
no2chem 0:b5d3bd64d2dc 281 for (i=0; i<N; i++) {
no2chem 0:b5d3bd64d2dc 282 for (j=0; j<N; j++) {
no2chem 0:b5d3bd64d2dc 283 C[i*N+j]=0;
no2chem 0:b5d3bd64d2dc 284 for(k=0;k<N;k++)
no2chem 0:b5d3bd64d2dc 285 {
no2chem 0:b5d3bd64d2dc 286 C[i*N+j]+=(MATRES)A[i*N+k] * (MATRES)B[k*N+j];
no2chem 0:b5d3bd64d2dc 287 }
no2chem 0:b5d3bd64d2dc 288 }
no2chem 0:b5d3bd64d2dc 289 }
no2chem 0:b5d3bd64d2dc 290 }
no2chem 0:b5d3bd64d2dc 291
no2chem 0:b5d3bd64d2dc 292 /* Function: matrix_mul_matrix_bitextract
no2chem 0:b5d3bd64d2dc 293 Multiply a matrix by a matrix, and extract some bits from the result.
no2chem 0:b5d3bd64d2dc 294 Basic code is used in many algorithms, mostly with minor changes such as scaling.
no2chem 0:b5d3bd64d2dc 295 */
no2chem 0:b5d3bd64d2dc 296 void matrix_mul_matrix_bitextract(ee_u32 N, MATRES *C, MATDAT *A, MATDAT *B) {
no2chem 0:b5d3bd64d2dc 297 ee_u32 i,j,k;
no2chem 0:b5d3bd64d2dc 298 for (i=0; i<N; i++) {
no2chem 0:b5d3bd64d2dc 299 for (j=0; j<N; j++) {
no2chem 0:b5d3bd64d2dc 300 C[i*N+j]=0;
no2chem 0:b5d3bd64d2dc 301 for(k=0;k<N;k++)
no2chem 0:b5d3bd64d2dc 302 {
no2chem 0:b5d3bd64d2dc 303 MATRES tmp=(MATRES)A[i*N+k] * (MATRES)B[k*N+j];
no2chem 0:b5d3bd64d2dc 304 C[i*N+j]+=bit_extract(tmp,2,4)*bit_extract(tmp,5,7);
no2chem 0:b5d3bd64d2dc 305 }
no2chem 0:b5d3bd64d2dc 306 }
no2chem 0:b5d3bd64d2dc 307 }
no2chem 0:b5d3bd64d2dc 308 }