1 // See LICENSE for license details.
3 //**************************************************************************
5 //--------------------------------------------------------------------------
7 // This is the classic Dhrystone synthetic integer benchmark.
10 #pragma GCC optimize ("no-inline")
12 #include "dhrystone.h"
14 void debug_printf(const char* str
, ...);
20 /* Global Variables: */
29 int Arr_2_Glob
[50] [50];
31 Enumeration
Func_1 ();
32 /* forward declaration necessary since Enumeration may not simply be int */
37 /* REG becomes defined as empty */
38 /* i.e. no register variables */
51 Dhrystones_Per_Second
;
53 /* end of variables for time measurement */
56 int main (int argc
, char** argv
)
58 /* main program, corresponds to procedures */
59 /* Main and Proc_0 in the Ada version */
62 REG One_Fifty Int_2_Loc
;
69 REG
int Number_Of_Runs
;
72 Number_Of_Runs
= NUMBER_OF_RUNS
;
76 Next_Ptr_Glob
= (Rec_Pointer
) alloca (sizeof (Rec_Type
));
77 Ptr_Glob
= (Rec_Pointer
) alloca (sizeof (Rec_Type
));
79 Ptr_Glob
->Ptr_Comp
= Next_Ptr_Glob
;
80 Ptr_Glob
->Discr
= Ident_1
;
81 Ptr_Glob
->variant
.var_1
.Enum_Comp
= Ident_3
;
82 Ptr_Glob
->variant
.var_1
.Int_Comp
= 40;
83 strcpy (Ptr_Glob
->variant
.var_1
.Str_Comp
,
84 "DHRYSTONE PROGRAM, SOME STRING");
85 strcpy (Str_1_Loc
, "DHRYSTONE PROGRAM, 1'ST STRING");
87 Arr_2_Glob
[8][7] = 10;
88 /* Was missing in published program. Without this statement, */
89 /* Arr_2_Glob [8][7] would have an undefined value. */
90 /* Warning: With 16-Bit processors and Number_Of_Runs > 32000, */
91 /* overflow may occur for this array element. */
94 debug_printf("Dhrystone Benchmark, Version %s\n", Version
);
97 debug_printf("Program compiled with 'register' attribute\n");
101 debug_printf("Program compiled without 'register' attribute\n");
103 debug_printf("Using %s, HZ=%d\n", CLOCK_TYPE
, HZ
);
108 debug_printf("Trying %d runs through Dhrystone:\n", Number_Of_Runs
);
117 for (Run_Index
= 1; Run_Index
<= Number_Of_Runs
; ++Run_Index
)
122 /* Ch_1_Glob == 'A', Ch_2_Glob == 'B', Bool_Glob == true */
125 strcpy (Str_2_Loc
, "DHRYSTONE PROGRAM, 2'ND STRING");
127 Bool_Glob
= ! Func_2 (Str_1_Loc
, Str_2_Loc
);
129 while (Int_1_Loc
< Int_2_Loc
) /* loop body executed once */
131 Int_3_Loc
= 5 * Int_1_Loc
- Int_2_Loc
;
133 Proc_7 (Int_1_Loc
, Int_2_Loc
, &Int_3_Loc
);
137 /* Int_1_Loc == 3, Int_2_Loc == 3, Int_3_Loc == 7 */
138 Proc_8 (Arr_1_Glob
, Arr_2_Glob
, Int_1_Loc
, Int_3_Loc
);
141 for (Ch_Index
= 'A'; Ch_Index
<= Ch_2_Glob
; ++Ch_Index
)
142 /* loop body executed twice */
144 if (Enum_Loc
== Func_1 (Ch_Index
, 'C'))
145 /* then, not executed */
147 Proc_6 (Ident_1
, &Enum_Loc
);
148 strcpy (Str_2_Loc
, "DHRYSTONE PROGRAM, 3'RD STRING");
149 Int_2_Loc
= Run_Index
;
150 Int_Glob
= Run_Index
;
153 /* Int_1_Loc == 3, Int_2_Loc == 3, Int_3_Loc == 7 */
154 Int_2_Loc
= Int_2_Loc
* Int_1_Loc
;
155 Int_1_Loc
= Int_2_Loc
/ Int_3_Loc
;
156 Int_2_Loc
= 7 * (Int_2_Loc
- Int_3_Loc
) - Int_1_Loc
;
157 /* Int_1_Loc == 1, Int_2_Loc == 13, Int_3_Loc == 7 */
161 } /* loop "for Run_Index" */
170 User_Time
= End_Time
- Begin_Time
;
172 if (User_Time
< Too_Small_Time
)
174 printf("Measured time too small to obtain meaningful results\n");
175 Number_Of_Runs
= Number_Of_Runs
* 10;
180 debug_printf("Final values of the variables used in the benchmark:\n");
182 debug_printf("Int_Glob: %d\n", Int_Glob
);
183 debug_printf(" should be: %d\n", 5);
184 debug_printf("Bool_Glob: %d\n", Bool_Glob
);
185 debug_printf(" should be: %d\n", 1);
186 debug_printf("Ch_1_Glob: %c\n", Ch_1_Glob
);
187 debug_printf(" should be: %c\n", 'A');
188 debug_printf("Ch_2_Glob: %c\n", Ch_2_Glob
);
189 debug_printf(" should be: %c\n", 'B');
190 debug_printf("Arr_1_Glob[8]: %d\n", Arr_1_Glob
[8]);
191 debug_printf(" should be: %d\n", 7);
192 debug_printf("Arr_2_Glob[8][7]: %d\n", Arr_2_Glob
[8][7]);
193 debug_printf(" should be: Number_Of_Runs + 10\n");
194 debug_printf("Ptr_Glob->\n");
195 debug_printf(" Ptr_Comp: %d\n", (long) Ptr_Glob
->Ptr_Comp
);
196 debug_printf(" should be: (implementation-dependent)\n");
197 debug_printf(" Discr: %d\n", Ptr_Glob
->Discr
);
198 debug_printf(" should be: %d\n", 0);
199 debug_printf(" Enum_Comp: %d\n", Ptr_Glob
->variant
.var_1
.Enum_Comp
);
200 debug_printf(" should be: %d\n", 2);
201 debug_printf(" Int_Comp: %d\n", Ptr_Glob
->variant
.var_1
.Int_Comp
);
202 debug_printf(" should be: %d\n", 17);
203 debug_printf(" Str_Comp: %s\n", Ptr_Glob
->variant
.var_1
.Str_Comp
);
204 debug_printf(" should be: DHRYSTONE PROGRAM, SOME STRING\n");
205 debug_printf("Next_Ptr_Glob->\n");
206 debug_printf(" Ptr_Comp: %d\n", (long) Next_Ptr_Glob
->Ptr_Comp
);
207 debug_printf(" should be: (implementation-dependent), same as above\n");
208 debug_printf(" Discr: %d\n", Next_Ptr_Glob
->Discr
);
209 debug_printf(" should be: %d\n", 0);
210 debug_printf(" Enum_Comp: %d\n", Next_Ptr_Glob
->variant
.var_1
.Enum_Comp
);
211 debug_printf(" should be: %d\n", 1);
212 debug_printf(" Int_Comp: %d\n", Next_Ptr_Glob
->variant
.var_1
.Int_Comp
);
213 debug_printf(" should be: %d\n", 18);
214 debug_printf(" Str_Comp: %s\n",
215 Next_Ptr_Glob
->variant
.var_1
.Str_Comp
);
216 debug_printf(" should be: DHRYSTONE PROGRAM, SOME STRING\n");
217 debug_printf("Int_1_Loc: %d\n", Int_1_Loc
);
218 debug_printf(" should be: %d\n", 5);
219 debug_printf("Int_2_Loc: %d\n", Int_2_Loc
);
220 debug_printf(" should be: %d\n", 13);
221 debug_printf("Int_3_Loc: %d\n", Int_3_Loc
);
222 debug_printf(" should be: %d\n", 7);
223 debug_printf("Enum_Loc: %d\n", Enum_Loc
);
224 debug_printf(" should be: %d\n", 1);
225 debug_printf("Str_1_Loc: %s\n", Str_1_Loc
);
226 debug_printf(" should be: DHRYSTONE PROGRAM, 1'ST STRING\n");
227 debug_printf("Str_2_Loc: %s\n", Str_2_Loc
);
228 debug_printf(" should be: DHRYSTONE PROGRAM, 2'ND STRING\n");
232 Microseconds
= ((User_Time
/ Number_Of_Runs
) * Mic_secs_Per_Second
) / HZ
;
233 Dhrystones_Per_Second
= (HZ
* Number_Of_Runs
) / User_Time
;
235 printf("Microseconds for one run through Dhrystone: %ld\n", Microseconds
);
236 printf("Dhrystones per Second: %ld\n", Dhrystones_Per_Second
);
245 REG Rec_Pointer Ptr_Val_Par
;
248 REG Rec_Pointer Next_Record
= Ptr_Val_Par
->Ptr_Comp
;
249 /* == Ptr_Glob_Next */
250 /* Local variable, initialized with Ptr_Val_Par->Ptr_Comp, */
251 /* corresponds to "rename" in Ada, "with" in Pascal */
253 structassign (*Ptr_Val_Par
->Ptr_Comp
, *Ptr_Glob
);
254 Ptr_Val_Par
->variant
.var_1
.Int_Comp
= 5;
255 Next_Record
->variant
.var_1
.Int_Comp
256 = Ptr_Val_Par
->variant
.var_1
.Int_Comp
;
257 Next_Record
->Ptr_Comp
= Ptr_Val_Par
->Ptr_Comp
;
258 Proc_3 (&Next_Record
->Ptr_Comp
);
259 /* Ptr_Val_Par->Ptr_Comp->Ptr_Comp
260 == Ptr_Glob->Ptr_Comp */
261 if (Next_Record
->Discr
== Ident_1
)
264 Next_Record
->variant
.var_1
.Int_Comp
= 6;
265 Proc_6 (Ptr_Val_Par
->variant
.var_1
.Enum_Comp
,
266 &Next_Record
->variant
.var_1
.Enum_Comp
);
267 Next_Record
->Ptr_Comp
= Ptr_Glob
->Ptr_Comp
;
268 Proc_7 (Next_Record
->variant
.var_1
.Int_Comp
, 10,
269 &Next_Record
->variant
.var_1
.Int_Comp
);
271 else /* not executed */
272 structassign (*Ptr_Val_Par
, *Ptr_Val_Par
->Ptr_Comp
);
279 /* *Int_Par_Ref == 1, becomes 4 */
281 One_Fifty
*Int_Par_Ref
;
284 Enumeration Enum_Loc
;
286 Int_Loc
= *Int_Par_Ref
+ 10;
287 do /* executed once */
288 if (Ch_1_Glob
== 'A')
292 *Int_Par_Ref
= Int_Loc
- Int_Glob
;
295 while (Enum_Loc
!= Ident_1
); /* true */
302 /* Ptr_Ref_Par becomes Ptr_Glob */
304 Rec_Pointer
*Ptr_Ref_Par
;
307 if (Ptr_Glob
!= Null
)
309 *Ptr_Ref_Par
= Ptr_Glob
->Ptr_Comp
;
310 Proc_7 (10, Int_Glob
, &Ptr_Glob
->variant
.var_1
.Int_Comp
);
314 Proc_4 () /* without parameters */
320 Bool_Loc
= Ch_1_Glob
== 'A';
321 Bool_Glob
= Bool_Loc
| Bool_Glob
;
326 Proc_5 () /* without parameters */