Skip to content

Commit ea8ef8d

Browse files
author
Hongyan Xia
committed
Port mibench benchmarks to CHERIoT
1 parent bc5fa11 commit ea8ef8d

16 files changed

+11085
-0
lines changed

tests/mibench_adpcm-test.cc

Lines changed: 304 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,304 @@
1+
/***********************************************************
2+
Copyright 1992 by Stichting Mathematisch Centrum, Amsterdam, The
3+
Netherlands.
4+
5+
All Rights Reserved
6+
7+
Permission to use, copy, modify, and distribute this software and its
8+
documentation for any purpose and without fee is hereby granted,
9+
provided that the above copyright notice appear in all copies and that
10+
both that copyright notice and this permission notice appear in
11+
supporting documentation, and that the names of Stichting Mathematisch
12+
Centrum or CWI not be used in advertising or publicity pertaining to
13+
distribution of the software without specific, written prior permission.
14+
15+
STICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO
16+
THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
17+
FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH CENTRUM BE LIABLE
18+
FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
19+
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
20+
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
21+
OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
22+
23+
******************************************************************/
24+
25+
/*
26+
** Intel/DVI ADPCM coder/decoder.
27+
**
28+
** The algorithm for this coder was taken from the IMA Compatability Project
29+
** proceedings, Vol 2, Number 2; May 1992.
30+
**
31+
** Version 1.2, 18-Dec-92.
32+
**
33+
** Change log:
34+
** - Fixed a stupid bug, where the delta was computed as
35+
** stepsize*code/4 in stead of stepsize*(code+0.5)/4.
36+
** - There was an off-by-one error causing it to pick
37+
** an incorrect delta once in a blue moon.
38+
** - The NODIVMUL define has been removed. Computations are now always done
39+
** using shifts, adds and subtracts. It turned out that, because the standard
40+
** is defined using shift/add/subtract, you needed bits of fixup code
41+
** (because the div/mul simulation using shift/add/sub made some rounding
42+
** errors that real div/mul don't make) and all together the resultant code
43+
** ran slower than just using the shifts all the time.
44+
** - Changed some of the variable names to be more meaningful.
45+
*/
46+
47+
#define TEST_NAME "MiBench-adpcm"
48+
#include <debug.hh>
49+
#include <stdlib.h>
50+
#include <string.h>
51+
#include "tests.hh"
52+
53+
struct adpcm_state {
54+
short valprev; /* Previous output value */
55+
char index; /* Index into stepsize table */
56+
};
57+
58+
void adpcm_coder(short *, char *, int, struct adpcm_state *);
59+
void adpcm_decoder(char *, short *, int, struct adpcm_state *);
60+
61+
#ifndef __STDC__
62+
#define signed
63+
#endif
64+
65+
/* Intel ADPCM step variation table */
66+
static int indexTable[16] = {
67+
-1, -1, -1, -1, 2, 4, 6, 8,
68+
-1, -1, -1, -1, 2, 4, 6, 8,
69+
};
70+
71+
static int stepsizeTable[89] = {
72+
7, 8, 9, 10, 11, 12, 13, 14, 16, 17,
73+
19, 21, 23, 25, 28, 31, 34, 37, 41, 45,
74+
50, 55, 60, 66, 73, 80, 88, 97, 107, 118,
75+
130, 143, 157, 173, 190, 209, 230, 253, 279, 307,
76+
337, 371, 408, 449, 494, 544, 598, 658, 724, 796,
77+
876, 963, 1060, 1166, 1282, 1411, 1552, 1707, 1878, 2066,
78+
2272, 2499, 2749, 3024, 3327, 3660, 4026, 4428, 4871, 5358,
79+
5894, 6484, 7132, 7845, 8630, 9493, 10442, 11487, 12635, 13899,
80+
15289, 16818, 18500, 20350, 22385, 24623, 27086, 29794, 32767
81+
};
82+
83+
void
84+
adpcm_coder(short * indata, char * outdata, int len,
85+
struct adpcm_state *state) {
86+
short * inp; /* Input buffer pointer */
87+
signed char * outp; /* output buffer pointer */
88+
int val; /* Current input sample value */
89+
int sign; /* Current adpcm sign bit */
90+
int delta; /* Current adpcm output value */
91+
int diff; /* Difference between val and valprev */
92+
int step; /* Stepsize */
93+
int valpred; /* Predicted output value */
94+
int vpdiff; /* Current change to valpred */
95+
int index; /* Current step change index */
96+
int outputbuffer; /* place to keep previous 4-bit value */
97+
int bufferstep; /* toggle between outputbuffer/output */
98+
99+
outp = (signed char *)outdata;
100+
inp = indata;
101+
102+
valpred = state->valprev;
103+
index = state->index;
104+
step = stepsizeTable[index];
105+
106+
bufferstep = 1;
107+
108+
for ( ; len > 0 ; len-- ) {
109+
val = *inp++;
110+
111+
/* Step 1 - compute difference with previous value */
112+
diff = val - valpred;
113+
sign = (diff < 0) ? 8 : 0;
114+
if ( sign ) diff = (-diff);
115+
116+
/* Step 2 - Divide and clamp */
117+
/* Note:
118+
** This code *approximately* computes:
119+
** delta = diff*4/step;
120+
** vpdiff = (delta+0.5)*step/4;
121+
** but in shift step bits are dropped. The net result of this is
122+
** that even if you have fast mul/div hardware you cannot put it to
123+
** good use since the fixup would be too expensive.
124+
*/
125+
delta = 0;
126+
vpdiff = (step >> 3);
127+
128+
if ( diff >= step ) {
129+
delta = 4;
130+
diff -= step;
131+
vpdiff += step;
132+
}
133+
step >>= 1;
134+
if ( diff >= step ) {
135+
delta |= 2;
136+
diff -= step;
137+
vpdiff += step;
138+
}
139+
step >>= 1;
140+
if ( diff >= step ) {
141+
delta |= 1;
142+
vpdiff += step;
143+
}
144+
145+
/* Step 3 - Update previous value */
146+
if ( sign )
147+
valpred -= vpdiff;
148+
else
149+
valpred += vpdiff;
150+
151+
/* Step 4 - Clamp previous value to 16 bits */
152+
if ( valpred > 32767 )
153+
valpred = 32767;
154+
else if ( valpred < -32768 )
155+
valpred = -32768;
156+
157+
/* Step 5 - Assemble value, update index and step values */
158+
delta |= sign;
159+
160+
index += indexTable[delta];
161+
if ( index < 0 ) index = 0;
162+
if ( index > 88 ) index = 88;
163+
step = stepsizeTable[index];
164+
165+
/* Step 6 - Output value */
166+
if ( bufferstep ) {
167+
outputbuffer = (delta << 4) & 0xf0;
168+
} else {
169+
*outp++ = (delta & 0x0f) | outputbuffer;
170+
}
171+
bufferstep = !bufferstep;
172+
}
173+
174+
/* Output last step, if needed */
175+
if ( !bufferstep )
176+
*outp++ = outputbuffer;
177+
178+
state->valprev = valpred;
179+
state->index = index;
180+
}
181+
182+
void
183+
adpcm_decoder(char * indata, short * outdata, int len,
184+
struct adpcm_state *state) {
185+
signed char * inp; /* Input buffer pointer */
186+
short * outp; /* output buffer pointer */
187+
int sign; /* Current adpcm sign bit */
188+
int delta; /* Current adpcm output value */
189+
int step; /* Stepsize */
190+
int valpred; /* Predicted value */
191+
int vpdiff; /* Current change to valpred */
192+
int index; /* Current step change index */
193+
int inputbuffer; /* place to keep next 4-bit value */
194+
int bufferstep; /* toggle between inputbuffer/input */
195+
196+
outp = outdata;
197+
inp = (signed char *)indata;
198+
199+
valpred = state->valprev;
200+
index = state->index;
201+
step = stepsizeTable[index];
202+
203+
bufferstep = 0;
204+
205+
for ( ; len > 0 ; len-- ) {
206+
207+
/* Step 1 - get the delta value */
208+
if ( bufferstep ) {
209+
delta = inputbuffer & 0xf;
210+
} else {
211+
inputbuffer = *inp++;
212+
delta = (inputbuffer >> 4) & 0xf;
213+
}
214+
bufferstep = !bufferstep;
215+
216+
/* Step 2 - Find new index value (for later) */
217+
index += indexTable[delta];
218+
if ( index < 0 ) index = 0;
219+
if ( index > 88 ) index = 88;
220+
221+
/* Step 3 - Separate sign and magnitude */
222+
sign = delta & 8;
223+
delta = delta & 7;
224+
225+
/* Step 4 - Compute difference and new predicted value */
226+
/*
227+
** Computes 'vpdiff = (delta+0.5)*step/4', but see comment
228+
** in adpcm_coder.
229+
*/
230+
vpdiff = step >> 3;
231+
if ( delta & 4 ) vpdiff += step;
232+
if ( delta & 2 ) vpdiff += step>>1;
233+
if ( delta & 1 ) vpdiff += step>>2;
234+
235+
if ( sign )
236+
valpred -= vpdiff;
237+
else
238+
valpred += vpdiff;
239+
240+
/* Step 5 - clamp output value */
241+
if ( valpred > 32767 )
242+
valpred = 32767;
243+
else if ( valpred < -32768 )
244+
valpred = -32768;
245+
246+
/* Step 6 - Update step value */
247+
step = stepsizeTable[index];
248+
249+
/* Step 7 - Output value */
250+
*outp++ = valpred;
251+
}
252+
253+
state->valprev = valpred;
254+
state->index = index;
255+
}
256+
257+
258+
struct adpcm_state state;
259+
260+
#define NSAMPLES 1024
261+
char abuf[NSAMPLES/2];
262+
short sbuf[NSAMPLES];
263+
char adpcmCcap[] = "Please put real data here!";
264+
char adpcmDcap[] = "Please put real data here!";
265+
266+
void test_mibench_adpcm()
267+
{
268+
// first, construct two capability to the buffers.
269+
char * abufcap = abuf;
270+
short * sbufcap = sbuf;
271+
272+
// second, construct two capabilities to the two data regions.
273+
size_t cSize = sizeof(adpcmCcap);
274+
size_t dSize = sizeof(adpcmDcap);
275+
276+
size_t totalProcessed = 0;
277+
size_t remain = 0;
278+
279+
/* encode stage */
280+
totalProcessed = 0;
281+
remain = 0;
282+
while((remain = cSize - totalProcessed) > NSAMPLES*2) {
283+
memcpy(sbufcap, adpcmCcap + totalProcessed, NSAMPLES*2);
284+
adpcm_coder(sbufcap, abufcap, NSAMPLES, &state);
285+
totalProcessed += NSAMPLES*2;
286+
}
287+
memcpy(sbufcap, adpcmCcap + totalProcessed, remain);
288+
adpcm_coder(sbufcap, abufcap, remain/2, &state);
289+
totalProcessed += remain;
290+
debug_log("adpcm encoded {} bytes in total.\n", totalProcessed);
291+
292+
/* decode stage, reinitialize variables. */
293+
totalProcessed = 0;
294+
remain = 0;
295+
while((remain = dSize - totalProcessed) > NSAMPLES/2) {
296+
memcpy(abufcap, adpcmDcap + totalProcessed, NSAMPLES/2);
297+
adpcm_decoder(abufcap, sbufcap, NSAMPLES, &state);
298+
totalProcessed += NSAMPLES/2;
299+
}
300+
memcpy(abufcap, adpcmDcap + totalProcessed, remain);
301+
adpcm_decoder(abufcap, sbufcap, remain*2, &state);
302+
totalProcessed += remain;
303+
debug_log("adpcm decoded {} bytes in total.", totalProcessed);
304+
}

0 commit comments

Comments
 (0)