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