1 /** A test based on the benchmark and its self-test
2 It is based on Dhrystone 2.1 by Reinhold P. Weicker.
7 #if !(defined(__SDCC_mcs51) && (defined(__SDCC_MODEL_SMALL) || defined(__SDCC_MODEL_MEDIUM))) && !defined(__SDCC_pdk14) && !defined(__SDCC_pdk15) && !defined(__SDCC_pic14) /* We need at least 5KB of memory */
9 #pragma disable_warning 84
10 #pragma disable_warning 85
12 #define Mic_secs_Per_Second 1000000.0
14 #define structassign(d, s) memcpy(&(d), &(s), sizeof(d))
20 typedef enum {Ident_1
, Ident_2
, Ident_3
, Ident_4
, Ident_5
} Enumeration
;
26 /* Value of a Null pointer */
30 typedef int One_Thirty
;
31 typedef int One_Fifty
;
32 typedef char Capital_Letter
;
34 typedef char Str_30
[31];
35 typedef int Arr_1_Dim
[50];
36 typedef int Arr_2_Dim
[50] [50];
40 struct record
*Ptr_Comp
;
44 Enumeration Enum_Comp
;
57 } Rec_Type
, *Rec_Pointer
;
59 void Proc_1 (REG Rec_Pointer Ptr_Val_Par
);
60 void Proc_2 (One_Fifty
*Int_Par_Ref
);
61 void Proc_3 (Rec_Pointer
*Ptr_Ref_Par
);
64 void Proc_6 (Enumeration Enum_Val_Par
, Enumeration
*Enum_Ref_Par
);
65 void Proc_7 (One_Fifty Int_1_Par_Val
, One_Fifty Int_2_Par_Val
, One_Fifty
*Int_Par_Ref
);
66 void Proc_8 (Arr_1_Dim Arr_1_Par_Ref
, Arr_2_Dim Arr_2_Par_Ref
, int Int_1_Par_Val
, int Int_2_Par_Val
);
67 Enumeration
Func_1 (Capital_Letter Ch_1_Par_Val
, Capital_Letter Ch_2_Par_Val
);
68 Boolean
Func_2 (Str_30 Str_1_Par_Ref
, Str_30 Str_2_Par_Ref
);
69 Boolean
Func_3 (Enumeration Enum_Par_Val
);
78 int Arr_2_Glob
[50] [50];
80 int scanf(const char *format
, ...);
85 /* REG becomes defined as empty */
88 #endif /* i.e. no register variables */
94 unsigned int clock(void);
95 #define CLOCKS_PER_SEC 1000
96 #define HZ CLOCKS_PER_SEC
99 #define Too_Small_Time 2000
105 Dhrystones_Per_Second
;
107 /* end of variables for time measurement */
114 void testDhrystone(void)
117 /* main program, corresponds to procedures */
118 /* Main and Proc_0 in the Ada version */
121 REG One_Fifty Int_2_Loc
;
124 Enumeration Enum_Loc
;
128 REG
int Number_Of_Runs
;
130 /* Initializations */
134 Next_Ptr_Glob
= /*(Rec_Pointer) malloc (sizeof (Rec_Type))*/ &malloc_1
;
135 Ptr_Glob
= /*(Rec_Pointer) malloc (sizeof (Rec_Type))*/ &malloc_2
;
137 Ptr_Glob
->Ptr_Comp
= Next_Ptr_Glob
;
138 Ptr_Glob
->Discr
= Ident_1
;
139 Ptr_Glob
->variant
.var_1
.Enum_Comp
= Ident_3
;
140 Ptr_Glob
->variant
.var_1
.Int_Comp
= 40;
141 strcpy (Ptr_Glob
->variant
.var_1
.Str_Comp
,
142 "DHRYSTONE PROGRAM, SOME STRING");
143 strcpy (Str_1_Loc
, "DHRYSTONE PROGRAM, 1'ST STRING");
145 Arr_2_Glob
[8][7] = 10;
146 /* Was missing in published program. Without this statement, */
147 /* Arr_2_Glob [8][7] would have an undefined value. */
148 /* Warning: With 16-Bit processors and Number_Of_Runs > 32000, */
149 /* overflow may occur for this array element. */
152 printf ("Dhrystone Benchmark, Version 2.1 (Language: C)\n");
156 printf ("Program compiled with 'register' attribute\n");
161 printf ("Program compiled without 'register' attribute\n");
164 printf ("Please give the number of runs through the benchmark: ");
167 /*scanf ("%d", &n)*/;
168 Number_Of_Runs
= 20/*n*/;
172 printf ("Execution starts, %d runs through Dhrystone\n", Number_Of_Runs
);
180 Begin_Time
= (long) time_info
.tms_utime
;
183 Begin_Time
= time ( (long *) 0);
186 Begin_Time
= clock();
189 for (Run_Index
= 1; Run_Index
<= Number_Of_Runs
; ++Run_Index
)
194 /* Ch_1_Glob == 'A', Ch_2_Glob == 'B', Bool_Glob == true */
197 strcpy (Str_2_Loc
, "DHRYSTONE PROGRAM, 2'ND STRING");
199 Bool_Glob
= ! Func_2 (Str_1_Loc
, Str_2_Loc
);
201 while (Int_1_Loc
< Int_2_Loc
) /* loop body executed once */
203 Int_3_Loc
= 5 * Int_1_Loc
- Int_2_Loc
;
205 Proc_7 (Int_1_Loc
, Int_2_Loc
, &Int_3_Loc
);
209 /* Int_1_Loc == 3, Int_2_Loc == 3, Int_3_Loc == 7 */
210 Proc_8 (Arr_1_Glob
, Arr_2_Glob
, Int_1_Loc
, Int_3_Loc
);
213 for (Ch_Index
= 'A'; Ch_Index
<= Ch_2_Glob
; ++Ch_Index
)
214 /* loop body executed twice */
216 if (Enum_Loc
== Func_1 (Ch_Index
, 'C'))
217 /* then, not executed */
219 Proc_6 (Ident_1
, &Enum_Loc
);
220 strcpy (Str_2_Loc
, "DHRYSTONE PROGRAM, 3'RD STRING");
221 Int_2_Loc
= Run_Index
;
222 Int_Glob
= Run_Index
;
225 /* Int_1_Loc == 3, Int_2_Loc == 3, Int_3_Loc == 7 */
226 Int_2_Loc
= Int_2_Loc
* Int_1_Loc
;
227 Int_1_Loc
= Int_2_Loc
/ Int_3_Loc
;
228 Int_2_Loc
= 7 * (Int_2_Loc
- Int_3_Loc
) - Int_1_Loc
;
229 /* Int_1_Loc == 1, Int_2_Loc == 13, Int_3_Loc == 7 */
233 } /* loop "for Run_Index" */
241 End_Time
= (long) time_info
.tms_utime
;
244 End_Time
= time ( (long *) 0);
250 printf ("Execution ends\n");
252 printf ("Final values of the variables used in the benchmark:\n");
254 printf ("Int_Glob: %d\n", Int_Glob
);
255 printf (" should be: %d\n", 5); ASSERT(Int_Glob
== 5);
256 printf ("Bool_Glob: %d\n", Bool_Glob
);
257 printf (" should be: %d\n", 1); ASSERT(Bool_Glob
== 1);
258 printf ("Ch_1_Glob: %c\n", Ch_1_Glob
);
259 printf (" should be: %c\n", 'A'); ASSERT(Ch_1_Glob
== 'A');
260 printf ("Ch_2_Glob: %c\n", Ch_2_Glob
);
261 printf (" should be: %c\n", 'B'); ASSERT(Ch_2_Glob
== 'B');
262 printf ("Arr_1_Glob[8]: %d\n", Arr_1_Glob
[8]);
263 printf (" should be: %d\n", 7); ASSERT(Arr_1_Glob
[8] == 7);
264 printf ("Arr_2_Glob[8][7]: %d\n", Arr_2_Glob
[8][7]);
265 printf (" should be: Number_Of_Runs + 10\n"); ASSERT(Arr_2_Glob
[8][7] == Number_Of_Runs
+ 10);
266 printf ("Ptr_Glob->\n");
267 printf (" Ptr_Comp: %d\n", (int) Ptr_Glob
->Ptr_Comp
);
268 printf (" should be: (implementation-dependent)\n");
269 printf (" Discr: %d\n", Ptr_Glob
->Discr
);
270 printf (" should be: %d\n", 0); ASSERT(Ptr_Glob
->Discr
== 0);
271 printf (" Enum_Comp: %d\n", Ptr_Glob
->variant
.var_1
.Enum_Comp
);
272 printf (" should be: %d\n", 2); ASSERT(Ptr_Glob
->variant
.var_1
.Enum_Comp
== 2);
273 printf (" Int_Comp: %d\n", Ptr_Glob
->variant
.var_1
.Int_Comp
);
274 printf (" should be: %d\n", 17); ASSERT(Ptr_Glob
->variant
.var_1
.Int_Comp
== 17);
275 printf (" Str_Comp: %s\n", Ptr_Glob
->variant
.var_1
.Str_Comp
);
276 printf (" should be: DHRYSTONE PROGRAM, SOME STRING\n"); ASSERT(!strcmp(Ptr_Glob
->variant
.var_1
.Str_Comp
, "DHRYSTONE PROGRAM, SOME STRING"));
277 printf ("Next_Ptr_Glob->\n");
278 printf (" Ptr_Comp: %d\n", (int) Next_Ptr_Glob
->Ptr_Comp
);
279 printf (" should be: (implementation-dependent), same as above\n"); ASSERT((int) Ptr_Glob
->Ptr_Comp
== (int) Next_Ptr_Glob
->Ptr_Comp
);
280 printf (" Discr: %d\n", Next_Ptr_Glob
->Discr
);
281 printf (" should be: %d\n", 0); ASSERT(Next_Ptr_Glob
->Discr
== 0);
282 printf (" Enum_Comp: %d\n", Next_Ptr_Glob
->variant
.var_1
.Enum_Comp
);
283 printf (" should be: %d\n", 1); ASSERT(Next_Ptr_Glob
->variant
.var_1
.Enum_Comp
== 1);
284 printf (" Int_Comp: %d\n", Next_Ptr_Glob
->variant
.var_1
.Int_Comp
);
285 printf (" should be: %d\n", 18); ASSERT(Next_Ptr_Glob
->variant
.var_1
.Int_Comp
== 18);
286 printf (" Str_Comp: %s\n",
287 Next_Ptr_Glob
->variant
.var_1
.Str_Comp
);
288 printf (" should be: DHRYSTONE PROGRAM, SOME STRING\n"); ASSERT(!strcmp(Next_Ptr_Glob
->variant
.var_1
.Str_Comp
, "DHRYSTONE PROGRAM, SOME STRING"));
289 printf ("Int_1_Loc: %d\n", Int_1_Loc
);
290 printf (" should be: %d\n", 5); ASSERT(Int_1_Loc
== 5);
291 printf ("Int_2_Loc: %d\n", Int_2_Loc
);
292 printf (" should be: %d\n", 13); ASSERT(Int_2_Loc
== 13);
293 printf ("Int_3_Loc: %d\n", Int_3_Loc
);
294 printf (" should be: %d\n", 7); ASSERT(Int_3_Loc
== 7);
295 printf ("Enum_Loc: %d\n", Enum_Loc
);
296 printf (" should be: %d\n", 1); ASSERT(Enum_Loc
== 1);
297 printf ("Str_1_Loc: %s\n", Str_1_Loc
);
298 printf (" should be: DHRYSTONE PROGRAM, 1'ST STRING\n"); ASSERT(!strcmp(Str_1_Loc
, "DHRYSTONE PROGRAM, 1'ST STRING"));
299 printf ("Str_2_Loc: %s\n", Str_2_Loc
);
300 printf (" should be: DHRYSTONE PROGRAM, 2'ND STRING\n"); ASSERT(!strcmp(Str_2_Loc
, "DHRYSTONE PROGRAM, 2'ND STRING"));
303 User_Time
= End_Time
- Begin_Time
;
305 if (User_Time
< Too_Small_Time
)
307 printf ("Measured time too small to obtain meaningful results\n");
308 printf ("Please increase number of runs\n");
314 Microseconds
= (float) User_Time
* Mic_secs_Per_Second
315 / (float) Number_Of_Runs
;
316 Dhrystones_Per_Second
= (float) Number_Of_Runs
/ (float) User_Time
;
318 Microseconds
= (float) User_Time
* Mic_secs_Per_Second
319 / ((float) HZ
* ((float) Number_Of_Runs
));
320 Dhrystones_Per_Second
= ((float) HZ
* (float) Number_Of_Runs
)
323 printf ("Microseconds for one run through Dhrystone: ");
324 //printf ("%6.1f \n", Microseconds);
325 printf ("%ld \n", (long int)Microseconds
);
326 printf ("Dhrystones per Second: ");
327 //printf ("%6.1f \n", Dhrystones_Per_Second);
328 printf ("%ld \n", (long int)Dhrystones_Per_Second
);
334 void Proc_1 (REG Rec_Pointer Ptr_Val_Par
)
340 REG Rec_Pointer Next_Record
= Ptr_Val_Par
->Ptr_Comp
;
341 /* == Ptr_Glob_Next */
342 /* Local variable, initialized with Ptr_Val_Par->Ptr_Comp, */
343 /* corresponds to "rename" in Ada, "with" in Pascal */
345 structassign (*Ptr_Val_Par
->Ptr_Comp
, *Ptr_Glob
);
346 Ptr_Val_Par
->variant
.var_1
.Int_Comp
= 5;
347 Next_Record
->variant
.var_1
.Int_Comp
348 = Ptr_Val_Par
->variant
.var_1
.Int_Comp
;
349 Next_Record
->Ptr_Comp
= Ptr_Val_Par
->Ptr_Comp
;
350 Proc_3 (&Next_Record
->Ptr_Comp
);
351 /* Ptr_Val_Par->Ptr_Comp->Ptr_Comp
352 == Ptr_Glob->Ptr_Comp */
353 if (Next_Record
->Discr
== Ident_1
)
356 Next_Record
->variant
.var_1
.Int_Comp
= 6;
357 Proc_6 (Ptr_Val_Par
->variant
.var_1
.Enum_Comp
,
358 &Next_Record
->variant
.var_1
.Enum_Comp
);
359 Next_Record
->Ptr_Comp
= Ptr_Glob
->Ptr_Comp
;
360 Proc_7 (Next_Record
->variant
.var_1
.Int_Comp
, 10,
361 &Next_Record
->variant
.var_1
.Int_Comp
);
363 else /* not executed */
364 structassign (*Ptr_Val_Par
, *Ptr_Val_Par
->Ptr_Comp
);
368 void Proc_2 (One_Fifty
*Int_Par_Ref
)
371 /* *Int_Par_Ref == 1, becomes 4 */
375 Enumeration Enum_Loc
;
377 Int_Loc
= *Int_Par_Ref
+ 10;
378 do /* executed once */
379 if (Ch_1_Glob
== 'A')
383 *Int_Par_Ref
= Int_Loc
- Int_Glob
;
386 while (Enum_Loc
!= Ident_1
); /* true */
390 void Proc_3 (Rec_Pointer
*Ptr_Ref_Par
)
393 /* Ptr_Ref_Par becomes Ptr_Glob */
396 if (Ptr_Glob
!= Null
)
398 *Ptr_Ref_Par
= Ptr_Glob
->Ptr_Comp
;
399 Proc_7 (10, Int_Glob
, &Ptr_Glob
->variant
.var_1
.Int_Comp
);
403 void Proc_4 (void) /* without parameters */
408 Bool_Loc
= Ch_1_Glob
== 'A';
409 Bool_Glob
= Bool_Loc
| Bool_Glob
;
414 void Proc_5 (void) /* without parameters */
423 extern char Ch_1_Glob
;
426 void Proc_6 (Enumeration Enum_Val_Par
, Enumeration
*Enum_Ref_Par
)
427 /*********************************/
429 /* Enum_Val_Par == Ident_3, Enum_Ref_Par becomes Ident_2 */
431 *Enum_Ref_Par
= Enum_Val_Par
;
432 if (! Func_3 (Enum_Val_Par
))
433 /* then, not executed */
434 *Enum_Ref_Par
= Ident_4
;
435 switch (Enum_Val_Par
)
438 *Enum_Ref_Par
= Ident_1
;
443 *Enum_Ref_Par
= Ident_1
;
444 else *Enum_Ref_Par
= Ident_4
;
446 case Ident_3
: /* executed */
447 *Enum_Ref_Par
= Ident_2
;
451 *Enum_Ref_Par
= Ident_3
;
457 void Proc_7 (One_Fifty Int_1_Par_Val
, One_Fifty Int_2_Par_Val
, One_Fifty
*Int_Par_Ref
)
458 /**********************************************/
459 /* executed three times */
460 /* first call: Int_1_Par_Val == 2, Int_2_Par_Val == 3, */
461 /* Int_Par_Ref becomes 7 */
462 /* second call: Int_1_Par_Val == 10, Int_2_Par_Val == 5, */
463 /* Int_Par_Ref becomes 17 */
464 /* third call: Int_1_Par_Val == 6, Int_2_Par_Val == 10, */
465 /* Int_Par_Ref becomes 18 */
469 Int_Loc
= Int_1_Par_Val
+ 2;
470 *Int_Par_Ref
= Int_2_Par_Val
+ Int_Loc
;
474 void Proc_8 (Arr_1_Dim Arr_1_Par_Ref
, Arr_2_Dim Arr_2_Par_Ref
, int Int_1_Par_Val
, int Int_2_Par_Val
)
475 /*********************************************************************/
477 /* Int_Par_Val_1 == 3 */
478 /* Int_Par_Val_2 == 7 */
480 REG One_Fifty Int_Index
;
481 REG One_Fifty Int_Loc
;
483 Int_Loc
= Int_1_Par_Val
+ 5;
484 Arr_1_Par_Ref
[Int_Loc
] = Int_2_Par_Val
;
485 Arr_1_Par_Ref
[Int_Loc
+1] = Arr_1_Par_Ref
[Int_Loc
];
486 Arr_1_Par_Ref
[Int_Loc
+30] = Int_Loc
;
487 for (Int_Index
= Int_Loc
; Int_Index
<= Int_Loc
+1; ++Int_Index
)
488 Arr_2_Par_Ref
[Int_Loc
] [Int_Index
] = Int_Loc
;
489 Arr_2_Par_Ref
[Int_Loc
] [Int_Loc
-1] += 1;
490 Arr_2_Par_Ref
[Int_Loc
+20] [Int_Loc
] = Arr_1_Par_Ref
[Int_Loc
];
495 Enumeration
Func_1 (Capital_Letter Ch_1_Par_Val
, Capital_Letter Ch_2_Par_Val
)
496 /*************************************************/
497 /* executed three times */
498 /* first call: Ch_1_Par_Val == 'H', Ch_2_Par_Val == 'R' */
499 /* second call: Ch_1_Par_Val == 'A', Ch_2_Par_Val == 'C' */
500 /* third call: Ch_1_Par_Val == 'B', Ch_2_Par_Val == 'C' */
503 Capital_Letter Ch_1_Loc
;
504 Capital_Letter Ch_2_Loc
;
506 Ch_1_Loc
= Ch_1_Par_Val
;
508 if (Ch_2_Loc
!= Ch_2_Par_Val
)
511 else /* not executed */
513 Ch_1_Glob
= Ch_1_Loc
;
519 Boolean
Func_2 (Str_30 Str_1_Par_Ref
, Str_30 Str_2_Par_Ref
)
520 /*************************************************/
522 /* Str_1_Par_Ref == "DHRYSTONE PROGRAM, 1'ST STRING" */
523 /* Str_2_Par_Ref == "DHRYSTONE PROGRAM, 2'ND STRING" */
526 REG One_Thirty Int_Loc
;
527 Capital_Letter Ch_Loc
;
530 while (Int_Loc
<= 2) /* loop body executed once */
531 if (Func_1 (Str_1_Par_Ref
[Int_Loc
],
532 Str_2_Par_Ref
[Int_Loc
+1]) == Ident_1
)
538 if (Ch_Loc
>= 'W' && Ch_Loc
< 'Z')
539 /* then, not executed */
542 /* then, not executed */
546 if (strcmp (Str_1_Par_Ref
, Str_2_Par_Ref
) > 0)
547 /* then, not executed */
559 Boolean
Func_3 (Enumeration Enum_Par_Val
)
560 /***************************/
562 /* Enum_Par_Val == Ident_3 */
564 Enumeration Enum_Loc
;
566 Enum_Loc
= Enum_Par_Val
;
567 if (Enum_Loc
== Ident_3
)
570 else /* not executed */
578 unsigned int clock(void)
583 #if !defined(PORT_HOST)
591 void testDhrystone(void)