Make dhrystone report correct-ish numbers
[riscv-tests.git] / benchmarks / dhrystone / dhrystone_main.c
1 // See LICENSE for license details.
2
3 //**************************************************************************
4 // Dhrystone bencmark
5 //--------------------------------------------------------------------------
6 //
7 // This is the classic Dhrystone synthetic integer benchmark.
8 // You should not change anything except the HOST_DEBUG and
9 // PREALLOCATE macros for your timing run.
10
11 #pragma GCC optimize ("no-inline")
12
13 #include "dhrystone.h"
14
15 //--------------------------------------------------------------------------
16 // Macros
17
18 // Set HOST_DEBUG to 1 if you are going to compile this for a host
19 // machine (ie Athena/Linux) for debug purposes and set HOST_DEBUG
20 // to 0 if you are compiling with the smips-gcc toolchain.
21
22 #ifndef HOST_DEBUG
23 #define HOST_DEBUG 0
24 #endif
25
26 // Set PREALLOCATE to 1 if you want to preallocate the benchmark
27 // function before starting stats. If you have instruction/data
28 // caches and you don't want to count the overhead of misses, then
29 // you will need to use preallocation.
30
31 #ifndef PREALLOCATE
32 #define PREALLOCATE 0
33 #endif
34
35 // Set SET_STATS to 1 if you want to carve out the piece that actually
36 // does the computation.
37
38 #ifndef SET_STATS
39 #define SET_STATS 0
40 #endif
41
42 #if HOST_DEBUG
43 # define debug_printf printf
44 #else
45 void debug_printf(const char* str, ...)
46 {
47 return 0;
48 }
49 #endif
50
51 #include "util.h"
52
53 #include <alloca.h>
54
55 /* Global Variables: */
56
57 Rec_Pointer Ptr_Glob,
58 Next_Ptr_Glob;
59 int Int_Glob;
60 Boolean Bool_Glob;
61 char Ch_1_Glob,
62 Ch_2_Glob;
63 int Arr_1_Glob [50];
64 int Arr_2_Glob [50] [50];
65
66 extern char *malloc ();
67 Enumeration Func_1 ();
68 /* forward declaration necessary since Enumeration may not simply be int */
69
70 #ifndef REG
71 Boolean Reg = false;
72 #define REG
73 /* REG becomes defined as empty */
74 /* i.e. no register variables */
75 #else
76 Boolean Reg = true;
77 #undef REG
78 #define REG register
79 #endif
80
81 Boolean Done;
82
83 long Begin_Time,
84 End_Time,
85 User_Time;
86 long Microseconds,
87 Dhrystones_Per_Second;
88
89 /* end of variables for time measurement */
90
91
92 int main (int argc, char** argv)
93 /*****/
94 /* main program, corresponds to procedures */
95 /* Main and Proc_0 in the Ada version */
96 {
97 One_Fifty Int_1_Loc;
98 REG One_Fifty Int_2_Loc;
99 One_Fifty Int_3_Loc;
100 REG char Ch_Index;
101 Enumeration Enum_Loc;
102 Str_30 Str_1_Loc;
103 Str_30 Str_2_Loc;
104 REG int Run_Index;
105 REG int Number_Of_Runs;
106
107 /* Arguments */
108 #if HOST_DEBUG
109 if (argc > 2)
110 {
111 printf("Usage: %s [number of loops]\n", argv[0]);
112 exit (1);
113 }
114 if (argc == 2)
115 {
116 Number_Of_Runs = atoi (argv[1]);
117 }
118 else if (Number_Of_Runs <= 0)
119 #endif
120 {
121 Number_Of_Runs = NUMBER_OF_RUNS;
122 }
123
124 /* Initializations */
125
126 Next_Ptr_Glob = (Rec_Pointer) alloca (sizeof (Rec_Type));
127 Ptr_Glob = (Rec_Pointer) alloca (sizeof (Rec_Type));
128
129 Ptr_Glob->Ptr_Comp = Next_Ptr_Glob;
130 Ptr_Glob->Discr = Ident_1;
131 Ptr_Glob->variant.var_1.Enum_Comp = Ident_3;
132 Ptr_Glob->variant.var_1.Int_Comp = 40;
133 strcpy (Ptr_Glob->variant.var_1.Str_Comp,
134 "DHRYSTONE PROGRAM, SOME STRING");
135 strcpy (Str_1_Loc, "DHRYSTONE PROGRAM, 1'ST STRING");
136
137 Arr_2_Glob [8][7] = 10;
138 /* Was missing in published program. Without this statement, */
139 /* Arr_2_Glob [8][7] would have an undefined value. */
140 /* Warning: With 16-Bit processors and Number_Of_Runs > 32000, */
141 /* overflow may occur for this array element. */
142
143 debug_printf("\n");
144 debug_printf("Dhrystone Benchmark, Version %s\n", Version);
145 if (Reg)
146 {
147 debug_printf("Program compiled with 'register' attribute\n");
148 }
149 else
150 {
151 debug_printf("Program compiled without 'register' attribute\n");
152 }
153 debug_printf("Using %s, HZ=%d\n", CLOCK_TYPE, HZ);
154 debug_printf("\n");
155
156 Done = false;
157 while (!Done) {
158 debug_printf("Trying %d runs through Dhrystone:\n", Number_Of_Runs);
159
160 /***************/
161 /* Start timer */
162 /***************/
163
164 Start_Timer();
165 setStats(1);
166
167 for (Run_Index = 1; Run_Index <= Number_Of_Runs; ++Run_Index)
168 {
169
170 Proc_5();
171 Proc_4();
172 /* Ch_1_Glob == 'A', Ch_2_Glob == 'B', Bool_Glob == true */
173 Int_1_Loc = 2;
174 Int_2_Loc = 3;
175 strcpy (Str_2_Loc, "DHRYSTONE PROGRAM, 2'ND STRING");
176 Enum_Loc = Ident_2;
177 Bool_Glob = ! Func_2 (Str_1_Loc, Str_2_Loc);
178 /* Bool_Glob == 1 */
179 while (Int_1_Loc < Int_2_Loc) /* loop body executed once */
180 {
181 Int_3_Loc = 5 * Int_1_Loc - Int_2_Loc;
182 /* Int_3_Loc == 7 */
183 Proc_7 (Int_1_Loc, Int_2_Loc, &Int_3_Loc);
184 /* Int_3_Loc == 7 */
185 Int_1_Loc += 1;
186 } /* while */
187 /* Int_1_Loc == 3, Int_2_Loc == 3, Int_3_Loc == 7 */
188 Proc_8 (Arr_1_Glob, Arr_2_Glob, Int_1_Loc, Int_3_Loc);
189 /* Int_Glob == 5 */
190 Proc_1 (Ptr_Glob);
191 for (Ch_Index = 'A'; Ch_Index <= Ch_2_Glob; ++Ch_Index)
192 /* loop body executed twice */
193 {
194 if (Enum_Loc == Func_1 (Ch_Index, 'C'))
195 /* then, not executed */
196 {
197 Proc_6 (Ident_1, &Enum_Loc);
198 strcpy (Str_2_Loc, "DHRYSTONE PROGRAM, 3'RD STRING");
199 Int_2_Loc = Run_Index;
200 Int_Glob = Run_Index;
201 }
202 }
203 /* Int_1_Loc == 3, Int_2_Loc == 3, Int_3_Loc == 7 */
204 Int_2_Loc = Int_2_Loc * Int_1_Loc;
205 Int_1_Loc = Int_2_Loc / Int_3_Loc;
206 Int_2_Loc = 7 * (Int_2_Loc - Int_3_Loc) - Int_1_Loc;
207 /* Int_1_Loc == 1, Int_2_Loc == 13, Int_3_Loc == 7 */
208 Proc_2 (&Int_1_Loc);
209 /* Int_1_Loc == 5 */
210
211 } /* loop "for Run_Index" */
212
213 /**************/
214 /* Stop timer */
215 /**************/
216
217 setStats(0);
218 Stop_Timer();
219
220 User_Time = End_Time - Begin_Time;
221
222 if (User_Time < Too_Small_Time)
223 {
224 printf("Measured time too small to obtain meaningful results\n");
225 Number_Of_Runs = Number_Of_Runs * 10;
226 printf("\n");
227 } else Done = true;
228 }
229
230 debug_printf("Final values of the variables used in the benchmark:\n");
231 debug_printf("\n");
232 debug_printf("Int_Glob: %d\n", Int_Glob);
233 debug_printf(" should be: %d\n", 5);
234 debug_printf("Bool_Glob: %d\n", Bool_Glob);
235 debug_printf(" should be: %d\n", 1);
236 debug_printf("Ch_1_Glob: %c\n", Ch_1_Glob);
237 debug_printf(" should be: %c\n", 'A');
238 debug_printf("Ch_2_Glob: %c\n", Ch_2_Glob);
239 debug_printf(" should be: %c\n", 'B');
240 debug_printf("Arr_1_Glob[8]: %d\n", Arr_1_Glob[8]);
241 debug_printf(" should be: %d\n", 7);
242 debug_printf("Arr_2_Glob[8][7]: %d\n", Arr_2_Glob[8][7]);
243 debug_printf(" should be: Number_Of_Runs + 10\n");
244 debug_printf("Ptr_Glob->\n");
245 debug_printf(" Ptr_Comp: %d\n", (long) Ptr_Glob->Ptr_Comp);
246 debug_printf(" should be: (implementation-dependent)\n");
247 debug_printf(" Discr: %d\n", Ptr_Glob->Discr);
248 debug_printf(" should be: %d\n", 0);
249 debug_printf(" Enum_Comp: %d\n", Ptr_Glob->variant.var_1.Enum_Comp);
250 debug_printf(" should be: %d\n", 2);
251 debug_printf(" Int_Comp: %d\n", Ptr_Glob->variant.var_1.Int_Comp);
252 debug_printf(" should be: %d\n", 17);
253 debug_printf(" Str_Comp: %s\n", Ptr_Glob->variant.var_1.Str_Comp);
254 debug_printf(" should be: DHRYSTONE PROGRAM, SOME STRING\n");
255 debug_printf("Next_Ptr_Glob->\n");
256 debug_printf(" Ptr_Comp: %d\n", (long) Next_Ptr_Glob->Ptr_Comp);
257 debug_printf(" should be: (implementation-dependent), same as above\n");
258 debug_printf(" Discr: %d\n", Next_Ptr_Glob->Discr);
259 debug_printf(" should be: %d\n", 0);
260 debug_printf(" Enum_Comp: %d\n", Next_Ptr_Glob->variant.var_1.Enum_Comp);
261 debug_printf(" should be: %d\n", 1);
262 debug_printf(" Int_Comp: %d\n", Next_Ptr_Glob->variant.var_1.Int_Comp);
263 debug_printf(" should be: %d\n", 18);
264 debug_printf(" Str_Comp: %s\n",
265 Next_Ptr_Glob->variant.var_1.Str_Comp);
266 debug_printf(" should be: DHRYSTONE PROGRAM, SOME STRING\n");
267 debug_printf("Int_1_Loc: %d\n", Int_1_Loc);
268 debug_printf(" should be: %d\n", 5);
269 debug_printf("Int_2_Loc: %d\n", Int_2_Loc);
270 debug_printf(" should be: %d\n", 13);
271 debug_printf("Int_3_Loc: %d\n", Int_3_Loc);
272 debug_printf(" should be: %d\n", 7);
273 debug_printf("Enum_Loc: %d\n", Enum_Loc);
274 debug_printf(" should be: %d\n", 1);
275 debug_printf("Str_1_Loc: %s\n", Str_1_Loc);
276 debug_printf(" should be: DHRYSTONE PROGRAM, 1'ST STRING\n");
277 debug_printf("Str_2_Loc: %s\n", Str_2_Loc);
278 debug_printf(" should be: DHRYSTONE PROGRAM, 2'ND STRING\n");
279 debug_printf("\n");
280
281
282 Microseconds = ((User_Time / Number_Of_Runs) * Mic_secs_Per_Second) / HZ;
283 Dhrystones_Per_Second = (HZ * Number_Of_Runs) / User_Time;
284
285 printf("Microseconds for one run through Dhrystone: %ld\n", Microseconds);
286 printf("Dhrystones per Second: %ld\n", Dhrystones_Per_Second);
287
288 return 0;
289 }
290
291
292 Proc_1 (Ptr_Val_Par)
293 /******************/
294
295 REG Rec_Pointer Ptr_Val_Par;
296 /* executed once */
297 {
298 REG Rec_Pointer Next_Record = Ptr_Val_Par->Ptr_Comp;
299 /* == Ptr_Glob_Next */
300 /* Local variable, initialized with Ptr_Val_Par->Ptr_Comp, */
301 /* corresponds to "rename" in Ada, "with" in Pascal */
302
303 structassign (*Ptr_Val_Par->Ptr_Comp, *Ptr_Glob);
304 Ptr_Val_Par->variant.var_1.Int_Comp = 5;
305 Next_Record->variant.var_1.Int_Comp
306 = Ptr_Val_Par->variant.var_1.Int_Comp;
307 Next_Record->Ptr_Comp = Ptr_Val_Par->Ptr_Comp;
308 Proc_3 (&Next_Record->Ptr_Comp);
309 /* Ptr_Val_Par->Ptr_Comp->Ptr_Comp
310 == Ptr_Glob->Ptr_Comp */
311 if (Next_Record->Discr == Ident_1)
312 /* then, executed */
313 {
314 Next_Record->variant.var_1.Int_Comp = 6;
315 Proc_6 (Ptr_Val_Par->variant.var_1.Enum_Comp,
316 &Next_Record->variant.var_1.Enum_Comp);
317 Next_Record->Ptr_Comp = Ptr_Glob->Ptr_Comp;
318 Proc_7 (Next_Record->variant.var_1.Int_Comp, 10,
319 &Next_Record->variant.var_1.Int_Comp);
320 }
321 else /* not executed */
322 structassign (*Ptr_Val_Par, *Ptr_Val_Par->Ptr_Comp);
323 } /* Proc_1 */
324
325
326 Proc_2 (Int_Par_Ref)
327 /******************/
328 /* executed once */
329 /* *Int_Par_Ref == 1, becomes 4 */
330
331 One_Fifty *Int_Par_Ref;
332 {
333 One_Fifty Int_Loc;
334 Enumeration Enum_Loc;
335
336 Int_Loc = *Int_Par_Ref + 10;
337 do /* executed once */
338 if (Ch_1_Glob == 'A')
339 /* then, executed */
340 {
341 Int_Loc -= 1;
342 *Int_Par_Ref = Int_Loc - Int_Glob;
343 Enum_Loc = Ident_1;
344 } /* if */
345 while (Enum_Loc != Ident_1); /* true */
346 } /* Proc_2 */
347
348
349 Proc_3 (Ptr_Ref_Par)
350 /******************/
351 /* executed once */
352 /* Ptr_Ref_Par becomes Ptr_Glob */
353
354 Rec_Pointer *Ptr_Ref_Par;
355
356 {
357 if (Ptr_Glob != Null)
358 /* then, executed */
359 *Ptr_Ref_Par = Ptr_Glob->Ptr_Comp;
360 Proc_7 (10, Int_Glob, &Ptr_Glob->variant.var_1.Int_Comp);
361 } /* Proc_3 */
362
363
364 Proc_4 () /* without parameters */
365 /*******/
366 /* executed once */
367 {
368 Boolean Bool_Loc;
369
370 Bool_Loc = Ch_1_Glob == 'A';
371 Bool_Glob = Bool_Loc | Bool_Glob;
372 Ch_2_Glob = 'B';
373 } /* Proc_4 */
374
375
376 Proc_5 () /* without parameters */
377 /*******/
378 /* executed once */
379 {
380 Ch_1_Glob = 'A';
381 Bool_Glob = false;
382 } /* Proc_5 */