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