37535e77beec2d81ab826177ec16dcf6dca98447
[riscv-tests.git] / benchmarks / dhrystone / dhrystone.h
1 // See LICENSE for license details.
2
3 #ifndef _DHRYSTONE_H
4 #define _DHRYSTONE_H
5
6 /****************** "DHRYSTONE" Benchmark Program ***************************/
7 #define Version "C, Version 2.2"
8 /* File: dhry_1.c (part 2 of 3)
9 * Author: Reinhold P. Weicker
10 * Siemens Nixdorf, Paderborn/Germany
11 * weicker@specbench.org
12 * Date: May 25, 1988
13 * Modified: Steven Pemberton, CWI, Amsterdam; Steven.Pemberton@cwi.nl
14 * Date: October, 1993; March 1995
15 * Included both files into one source, that gets compiled
16 * in two passes. Made program auto-compiling, and auto-running,
17 * and generally made it much easier to use.
18 *
19 * Original Version (in Ada) published in
20 * "Communications of the ACM" vol. 27., no. 10 (Oct. 1984),
21 * pp. 1013 - 1030, together with the statistics
22 * on which the distribution of statements etc. is based.
23 *
24 * In this C version, the following C library functions are used:
25 * - strcpy, strcmp (inside the measurement loop)
26 * - printf, scanf (outside the measurement loop)
27 * In addition, Berkeley UNIX system calls "times ()" or "time ()"
28 * are used for execution time measurement. For measurements
29 * on other systems, these calls have to be changed.
30 *
31 * Collection of Results:
32 * Reinhold Weicker (address see above) and
33 *
34 * Rick Richardson
35 * PC Research. Inc.
36 * 94 Apple Orchard Drive
37 * Tinton Falls, NJ 07724
38 * Phone: (201) 389-8963 (9-17 EST)
39 * Usenet: ...!uunet!pcrat!rick
40 *
41 * Please send results to Rick Richardson and/or Reinhold Weicker.
42 * Complete information should be given on hardware and software used.
43 * Hardware information includes: Machine type, CPU, type and size
44 * of caches; for microprocessors: clock frequency, memory speed
45 * (number of wait states).
46 * Software information includes: Compiler (and runtime library)
47 * manufacturer and version, compilation switches, OS version.
48 * The Operating System version may give an indication about the compiler;
49 * Dhrystone itself performs no OS calls in the measurement loop.
50 *
51 * The complete output generated by the program should be mailed
52 * such that at least some checks for correctness can be made.
53 *
54 ***************************************************************************
55 *
56 * Defines: The following "Defines" are possible:
57 * -DREG (default: Not defined)
58 * As an approximation to what an average C programmer
59 * might do, causes the "register" storage class to be applied
60 * - for local variables, if they are used (dynamically)
61 * five or more times
62 * - for parameters if they are used (dynamically)
63 * six or more times
64 * Note that an optimal "register" strategy is
65 * compiler-dependent, and that "register" declarations
66 * do not necessarily lead to faster execution.
67 * -DNOSTRUCTASSIGN (default: Not defined)
68 * Define if the C compiler does not support
69 * assignment of structures.
70 * -DNOENUMS (default: Not defined)
71 * Define if the C compiler does not support
72 * enumeration types.
73 * -DTIMES (default)
74 * -DTIME
75 * The "times" function of UNIX (returning process times)
76 * or the "time" function (returning wallclock time)
77 * is used for measurement.
78 * For single user machines, "time ()" is adequate. For
79 * multi-user machines where you cannot get single-user
80 * access, use the "times ()" function. If you have
81 * neither, use a stopwatch in the dead of night.
82 * "printf"s are provided marking the points "Start Timer"
83 * and "Stop Timer". DO NOT use the UNIX "time(1)"
84 * command, as this will measure the total time to
85 * run this program, which will (erroneously) include
86 * the time to allocate storage (malloc) and to perform
87 * the initialization.
88 * -DHZ=nnn
89 * In Berkeley UNIX, the function "times" returns process
90 * time in 1/HZ seconds, with HZ = 60 for most systems.
91 * CHECK YOUR SYSTEM DESCRIPTION BEFORE YOU JUST APPLY
92 * A VALUE.
93 *
94 ***************************************************************************
95 *
96 * History: Version C/2.1 was made for two reasons:
97 *
98 * 1) There was an obvious need for a common C version of
99 * Dhrystone, since C is at present the most popular system
100 * programming language for the class of processors
101 * (microcomputers, minicomputers) where Dhrystone is used most.
102 * There should be, as far as possible, only one C version of
103 * Dhrystone such that results can be compared without
104 * restrictions. In the past, the C versions distributed
105 * by Rick Richardson (Version 1.1) and by Reinhold Weicker
106 * had small (though not significant) differences.
107 *
108 * 2) As far as it is possible without changes to the Dhrystone
109 * statistics, optimizing compilers should be prevented from
110 * removing significant statements.
111 *
112 * This C version has been developed in cooperation with
113 * Rick Richardson (Tinton Falls, NJ), it incorporates many
114 * ideas from the "Version 1.1" distributed previously by
115 * him over the UNIX network Usenet.
116 * I also thank Chaim Benedelac (National Semiconductor),
117 * David Ditzel (SUN), Earl Killian and John Mashey (MIPS),
118 * Alan Smith and Rafael Saavedra-Barrera (UC at Berkeley)
119 * for their help with comments on earlier versions of the
120 * benchmark.
121 *
122 * Changes: In the initialization part, this version follows mostly
123 * Rick Richardson's version distributed via Usenet, not the
124 * version distributed earlier via floppy disk by Reinhold Weicker.
125 * As a concession to older compilers, names have been made
126 * unique within the first 8 characters.
127 * Inside the measurement loop, this version follows the
128 * version previously distributed by Reinhold Weicker.
129 *
130 * At several places in the benchmark, code has been added,
131 * but within the measurement loop only in branches that
132 * are not executed. The intention is that optimizing compilers
133 * should be prevented from moving code out of the measurement
134 * loop, or from removing code altogether. Since the statements
135 * that are executed within the measurement loop have NOT been
136 * changed, the numbers defining the "Dhrystone distribution"
137 * (distribution of statements, operand types and locality)
138 * still hold. Except for sophisticated optimizing compilers,
139 * execution times for this version should be the same as
140 * for previous versions.
141 *
142 * Since it has proven difficult to subtract the time for the
143 * measurement loop overhead in a correct way, the loop check
144 * has been made a part of the benchmark. This does have
145 * an impact - though a very minor one - on the distribution
146 * statistics which have been updated for this version.
147 *
148 * All changes within the measurement loop are described
149 * and discussed in the companion paper "Rationale for
150 * Dhrystone version 2".
151 *
152 * Because of the self-imposed limitation that the order and
153 * distribution of the executed statements should not be
154 * changed, there are still cases where optimizing compilers
155 * may not generate code for some statements. To a certain
156 * degree, this is unavoidable for small synthetic benchmarks.
157 * Users of the benchmark are advised to check code listings
158 * whether code is generated for all statements of Dhrystone.
159 *
160 * Version 2.1 is identical to version 2.0 distributed via
161 * the UNIX network Usenet in March 1988 except that it corrects
162 * some minor deficiencies that were found by users of version 2.0.
163 * The only change within the measurement loop is that a
164 * non-executed "else" part was added to the "if" statement in
165 * Func_3, and a non-executed "else" part removed from Proc_3.
166 *
167 * Version C/2.2, Steven Pemberton, October 1993
168 * Functionally, identical to version 2.2; the changes are in
169 * how you compile and use it:
170 * - Everything is in one file now, but compiled in 2 passes
171 * - Compile (and run) by running the file through the shell: 'sh dhry.c"
172 * - Uses the system definition of HZ if one can be found
173 * - HZ must be defined, otherwise it won't compile (no defaults here)
174 * - The (uninteresting) output is printed to stderr (dhry2 > /dev/null)
175 * - The number of loops is passed as a parameter, rather than read
176 * (dhry2 500000)
177 * - If the number of loops is insufficient to get a good result,
178 * it repeats it with loops*10 until it is enough (rather than just
179 * stopping)
180 * - Output says which sort of clock it is using, and the HZ value
181 * - You can use -DREG instead of the -DREG=register of previous versions
182 * - Some stylistic cleanups.
183 *
184 ***************************************************************************
185 *
186 * Compilation model and measurement (IMPORTANT):
187 *
188 * The following "ground rules" apply for measurements:
189 * - Separate compilation
190 * - No procedure merging
191 * - Otherwise, compiler optimizations are allowed but should be indicated
192 * - Default results are those without register declarations
193 * See the companion paper "Rationale for Dhrystone Version 2" for a more
194 * detailed discussion of these ground rules.
195 *
196 * For 16-Bit processors (e.g. 80186, 80286), times for all compilation
197 * models ("small", "medium", "large" etc.) should be given if possible,
198 * together with a definition of these models for the compiler system used.
199 *
200 **************************************************************************
201 *
202 * Dhrystone (C version) statistics:
203 *
204 * [Comment from the first distribution, updated for version 2.
205 * Note that because of language differences, the numbers are slightly
206 * different from the Ada version.]
207 *
208 * The following program contains statements of a high level programming
209 * language (here: C) in a distribution considered representative:
210 *
211 * assignments 52 (51.0 %)
212 * control statements 33 (32.4 %)
213 * procedure, function calls 17 (16.7 %)
214 *
215 * 103 statements are dynamically executed. The program is balanced with
216 * respect to the three aspects:
217 *
218 * - statement type
219 * - operand type
220 * - operand locality
221 * operand global, local, parameter, or constant.
222 *
223 * The combination of these three aspects is balanced only approximately.
224 *
225 * 1. Statement Type:
226 * ----------------- number
227 *
228 * V1 = V2 9
229 * (incl. V1 = F(..)
230 * V = Constant 12
231 * Assignment, 7
232 * with array element
233 * Assignment, 6
234 * with record component
235 * --
236 * 34 34
237 *
238 * X = Y +|-|"&&"|"|" Z 5
239 * X = Y +|-|"==" Constant 6
240 * X = X +|- 1 3
241 * X = Y *|/ Z 2
242 * X = Expression, 1
243 * two operators
244 * X = Expression, 1
245 * three operators
246 * --
247 * 18 18
248 *
249 * if .... 14
250 * with "else" 7
251 * without "else" 7
252 * executed 3
253 * not executed 4
254 * for ... 7 | counted every time
255 * while ... 4 | the loop condition
256 * do ... while 1 | is evaluated
257 * switch ... 1
258 * break 1
259 * declaration with 1
260 * initialization
261 * --
262 * 34 34
263 *
264 * P (...) procedure call 11
265 * user procedure 10
266 * library procedure 1
267 * X = F (...)
268 * function call 6
269 * user function 5
270 * library function 1
271 * --
272 * 17 17
273 * ---
274 * 103
275 *
276 * The average number of parameters in procedure or function calls
277 * is 1.82 (not counting the function values aX *
278 *
279 * 2. Operators
280 * ------------
281 * number approximate
282 * percentage
283 *
284 * Arithmetic 32 50.8
285 *
286 * + 21 33.3
287 * - 7 11.1
288 * * 3 4.8
289 * / (int div) 1 1.6
290 *
291 * Comparison 27 42.8
292 *
293 * == 9 14.3
294 * /= 4 6.3
295 * > 1 1.6
296 * < 3 4.8
297 * >= 1 1.6
298 * <= 9 14.3
299 *
300 * Logic 4 6.3
301 *
302 * && (AND-THEN) 1 1.6
303 * | (OR) 1 1.6
304 * ! (NOT) 2 3.2
305 *
306 * -- -----
307 * 63 100.1
308 *
309 *
310 * 3. Operand Type (counted once per operand reference):
311 * ---------------
312 * number approximate
313 * percentage
314 *
315 * Integer 175 72.3 %
316 * Character 45 18.6 %
317 * Pointer 12 5.0 %
318 * String30 6 2.5 %
319 * Array 2 0.8 %
320 * Record 2 0.8 %
321 * --- -------
322 * 242 100.0 %
323 *
324 * When there is an access path leading to the final operand (e.g. a record
325 * component), only the final data type on the access path is counted.
326 *
327 *
328 * 4. Operand Locality:
329 * -------------------
330 * number approximate
331 * percentage
332 *
333 * local variable 114 47.1 %
334 * global variable 22 9.1 %
335 * parameter 45 18.6 %
336 * value 23 9.5 %
337 * reference 22 9.1 %
338 * function result 6 2.5 %
339 * constant 55 22.7 %
340 * --- -------
341 * 242 100.0 %
342 *
343 * The program does not compute anything meaningful, but it is syntactically
344 * and semantically correct. All variables have a value assigned to them
345 * before they are used as a source operand.
346 *
347 * There has been no explicit effort to account for the effects of a
348 * cache, or to balance the use of long or short displacements for code or
349 * data.
350 *
351 ***************************************************************************
352 */
353
354 /* Compiler and system dependent definitions: */
355
356 /* variables for time measurement: */
357
358 #ifdef TIME
359
360 #define CLOCK_TYPE "time()"
361 #undef HZ
362 #define HZ (1) /* time() returns time in seconds */
363 extern long time(); /* see library function "time" */
364 #define Too_Small_Time 2 /* Measurements should last at least 2 seconds */
365 #define Start_Timer() Begin_Time = time ( (long *) 0)
366 #define Stop_Timer() End_Time = time ( (long *) 0)
367
368 #else
369
370 #ifdef MSC_CLOCK /* Use Microsoft C hi-res clock */
371
372 #undef HZ
373 #undef TIMES
374 #include <time.h>
375 #define HZ CLK_TCK
376 #define CLOCK_TYPE "MSC clock()"
377 extern clock_t clock();
378 #define Too_Small_Time (2*HZ)
379 #define Start_Timer() Begin_Time = clock()
380 #define Stop_Timer() End_Time = clock()
381
382 #elif defined(__riscv)
383
384 #define HZ 1000000
385 #define Too_Small_Time 1
386 #define CLOCK_TYPE "rdcycle()"
387 #define Start_Timer() Begin_Time = rdcycle()
388 #define Stop_Timer() End_Time = rdcycle()
389
390 #else
391 /* Use times(2) time function unless */
392 /* explicitly defined otherwise */
393 #define CLOCK_TYPE "times()"
394 #include <sys/types.h>
395 #include <sys/times.h>
396 #ifndef HZ /* Added by SP 900619 */
397 #include <sys/param.h> /* If your system doesn't have this, use -DHZ=xxx */
398 #else
399 *** You must define HZ!!! ***
400 #endif /* HZ */
401 #ifndef PASS2
402 struct tms time_info;
403 #endif
404 /*extern int times ();*/
405 /* see library function "times" */
406 #define Too_Small_Time (2*HZ)
407 /* Measurements should last at least about 2 seconds */
408 #define Start_Timer() times(&time_info); Begin_Time=(long)time_info.tms_utime
409 #define Stop_Timer() times(&time_info); End_Time = (long)time_info.tms_utime
410
411 #endif /* MSC_CLOCK */
412 #endif /* TIME */
413
414
415 #define Mic_secs_Per_Second 1000000.0
416 #define NUMBER_OF_RUNS 500 /* Default number of runs */
417
418 #ifdef NOSTRUCTASSIGN
419 #define structassign(d, s) memcpy(&(d), &(s), sizeof(d))
420 #else
421 #define structassign(d, s) d = s
422 #endif
423
424 #ifdef NOENUM
425 #define Ident_1 0
426 #define Ident_2 1
427 #define Ident_3 2
428 #define Ident_4 3
429 #define Ident_5 4
430 typedef int Enumeration;
431 #else
432 typedef enum {Ident_1, Ident_2, Ident_3, Ident_4, Ident_5}
433 Enumeration;
434 #endif
435 /* for boolean and enumeration types in Ada, Pascal */
436
437 /* General definitions: */
438
439 #include <stdio.h>
440 #include <string.h>
441 /* for strcpy, strcmp */
442
443 #define Null 0
444 /* Value of a Null pointer */
445 #define true 1
446 #define false 0
447
448 typedef int One_Thirty;
449 typedef int One_Fifty;
450 typedef char Capital_Letter;
451 typedef int Boolean;
452 typedef char Str_30 [31];
453 typedef int Arr_1_Dim [50];
454 typedef int Arr_2_Dim [50] [50];
455
456 typedef struct record
457 {
458 struct record *Ptr_Comp;
459 Enumeration Discr;
460 union {
461 struct {
462 Enumeration Enum_Comp;
463 int Int_Comp;
464 char Str_Comp [31];
465 } var_1;
466 struct {
467 Enumeration E_Comp_2;
468 char Str_2_Comp [31];
469 } var_2;
470 struct {
471 char Ch_1_Comp;
472 char Ch_2_Comp;
473 } var_3;
474 } variant;
475 } Rec_Type, *Rec_Pointer;
476
477 #endif