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