struct / union in initializer, RFE #901.
[sdcc.git] / sdcc / support / regression / tests / dhrystone.c
blob2ccb57cf5eba5b201e4504bc8fdd6e75553a8109
1 /** A test based on the benchmark and its self-test
2 It is based on Dhrystone 2.1 by Reinhold P. Weicker.
3 */
5 #include <testfwk.h>
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))
16 #ifndef REG
17 #define REG
18 #endif
20 typedef enum {Ident_1, Ident_2, Ident_3, Ident_4, Ident_5} Enumeration;
22 #include <stdio.h>
23 #include <string.h>
25 #define Null 0
26 /* Value of a Null pointer */
27 #define true 1
28 #define false 0
30 typedef int One_Thirty;
31 typedef int One_Fifty;
32 typedef char Capital_Letter;
33 typedef int Boolean;
34 typedef char Str_30 [31];
35 typedef int Arr_1_Dim [50];
36 typedef int Arr_2_Dim [50] [50];
38 typedef struct record
40 struct record *Ptr_Comp;
41 Enumeration Discr;
42 union {
43 struct {
44 Enumeration Enum_Comp;
45 int Int_Comp;
46 char Str_Comp [31];
47 } var_1;
48 struct {
49 Enumeration E_Comp_2;
50 char Str_2_Comp [31];
51 } var_2;
52 struct {
53 char Ch_1_Comp;
54 char Ch_2_Comp;
55 } var_3;
56 } variant;
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);
62 void Proc_4 (void);
63 void Proc_5 (void);
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);
71 Rec_Pointer Ptr_Glob,
72 Next_Ptr_Glob;
73 int Int_Glob;
74 Boolean Bool_Glob;
75 char Ch_1_Glob,
76 Ch_2_Glob;
77 int Arr_1_Glob [50];
78 int Arr_2_Glob [50] [50];
80 int scanf(const char *format, ...);
82 #ifndef REG
83 Boolean Reg = false;
84 #define REG
85 /* REG becomes defined as empty */
86 #ifndef REG
87 #define REG
88 #endif /* i.e. no register variables */
89 #else
90 Boolean Reg = true;
91 #endif
93 #if 1
94 unsigned int clock(void);
95 #define CLOCKS_PER_SEC 1000
96 #define HZ CLOCKS_PER_SEC
97 #endif
99 #define Too_Small_Time 2000
101 long Begin_Time,
102 End_Time,
103 User_Time;
104 float Microseconds,
105 Dhrystones_Per_Second;
107 /* end of variables for time measurement */
109 void init(void);
111 Rec_Type malloc_1;
112 Rec_Type malloc_2;
114 void testDhrystone(void)
115 /*****/
117 /* main program, corresponds to procedures */
118 /* Main and Proc_0 in the Ada version */
120 One_Fifty Int_1_Loc;
121 REG One_Fifty Int_2_Loc;
122 One_Fifty Int_3_Loc;
123 REG char Ch_Index;
124 Enumeration Enum_Loc;
125 Str_30 Str_1_Loc;
126 Str_30 Str_2_Loc;
127 REG int Run_Index;
128 REG int Number_Of_Runs;
130 /* Initializations */
132 init();
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. */
151 printf ("\n");
152 printf ("Dhrystone Benchmark, Version 2.1 (Language: C)\n");
153 printf ("\n");
154 if (Reg)
156 printf ("Program compiled with 'register' attribute\n");
157 printf ("\n");
159 else
161 printf ("Program compiled without 'register' attribute\n");
162 printf ("\n");
164 printf ("Please give the number of runs through the benchmark: ");
166 int n;
167 /*scanf ("%d", &n)*/;
168 Number_Of_Runs = 20/*n*/;
170 printf ("\n");
172 printf ("Execution starts, %d runs through Dhrystone\n", Number_Of_Runs);
174 /***************/
175 /* Start timer */
176 /***************/
178 #ifdef TIMES
179 times (&time_info);
180 Begin_Time = (long) time_info.tms_utime;
181 #endif
182 #ifdef TIME
183 Begin_Time = time ( (long *) 0);
184 #endif
185 #if 1
186 Begin_Time = clock();
187 #endif
189 for (Run_Index = 1; Run_Index <= Number_Of_Runs; ++Run_Index)
192 Proc_5();
193 Proc_4();
194 /* Ch_1_Glob == 'A', Ch_2_Glob == 'B', Bool_Glob == true */
195 Int_1_Loc = 2;
196 Int_2_Loc = 3;
197 strcpy (Str_2_Loc, "DHRYSTONE PROGRAM, 2'ND STRING");
198 Enum_Loc = Ident_2;
199 Bool_Glob = ! Func_2 (Str_1_Loc, Str_2_Loc);
200 /* Bool_Glob == 1 */
201 while (Int_1_Loc < Int_2_Loc) /* loop body executed once */
203 Int_3_Loc = 5 * Int_1_Loc - Int_2_Loc;
204 /* Int_3_Loc == 7 */
205 Proc_7 (Int_1_Loc, Int_2_Loc, &Int_3_Loc);
206 /* Int_3_Loc == 7 */
207 Int_1_Loc += 1;
208 } /* while */
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);
211 /* Int_Glob == 5 */
212 Proc_1 (Ptr_Glob);
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 */
230 Proc_2 (&Int_1_Loc);
231 /* Int_1_Loc == 5 */
233 } /* loop "for Run_Index" */
235 /**************/
236 /* Stop timer */
237 /**************/
239 #ifdef TIMES
240 times (&time_info);
241 End_Time = (long) time_info.tms_utime;
242 #endif
243 #ifdef TIME
244 End_Time = time ( (long *) 0);
245 #endif
246 #if 1
247 End_Time = clock();
248 #endif
250 printf ("Execution ends\n");
251 printf ("\n");
252 printf ("Final values of the variables used in the benchmark:\n");
253 printf ("\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"));
301 printf ("\n");
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");
309 printf ("\n");
311 else
313 #ifdef TIME
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;
317 #else
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)
321 / (float) User_Time;
322 #endif
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);
329 printf ("\n");
334 void Proc_1 (REG Rec_Pointer Ptr_Val_Par)
335 /******************/
338 /* executed once */
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)
354 /* then, executed */
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);
365 } /* Proc_1 */
368 void Proc_2 (One_Fifty *Int_Par_Ref)
369 /******************/
370 /* executed once */
371 /* *Int_Par_Ref == 1, becomes 4 */
374 One_Fifty Int_Loc;
375 Enumeration Enum_Loc;
377 Int_Loc = *Int_Par_Ref + 10;
378 do /* executed once */
379 if (Ch_1_Glob == 'A')
380 /* then, executed */
382 Int_Loc -= 1;
383 *Int_Par_Ref = Int_Loc - Int_Glob;
384 Enum_Loc = Ident_1;
385 } /* if */
386 while (Enum_Loc != Ident_1); /* true */
387 } /* Proc_2 */
390 void Proc_3 (Rec_Pointer *Ptr_Ref_Par)
391 /******************/
392 /* executed once */
393 /* Ptr_Ref_Par becomes Ptr_Glob */
396 if (Ptr_Glob != Null)
397 /* then, executed */
398 *Ptr_Ref_Par = Ptr_Glob->Ptr_Comp;
399 Proc_7 (10, Int_Glob, &Ptr_Glob->variant.var_1.Int_Comp);
400 } /* Proc_3 */
403 void Proc_4 (void) /* without parameters */
404 /*******/
405 /* executed once */
407 Boolean Bool_Loc;
408 Bool_Loc = Ch_1_Glob == 'A';
409 Bool_Glob = Bool_Loc | Bool_Glob;
410 Ch_2_Glob = 'B';
411 } /* Proc_4 */
414 void Proc_5 (void) /* without parameters */
415 /*******/
416 /* executed once */
418 Ch_1_Glob = 'A';
419 Bool_Glob = false;
420 } /* Proc_5 */
422 extern int Int_Glob;
423 extern char Ch_1_Glob;
426 void Proc_6 (Enumeration Enum_Val_Par, Enumeration *Enum_Ref_Par)
427 /*********************************/
428 /* executed once */
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)
437 case Ident_1:
438 *Enum_Ref_Par = Ident_1;
439 break;
440 case Ident_2:
441 if (Int_Glob > 100)
442 /* then */
443 *Enum_Ref_Par = Ident_1;
444 else *Enum_Ref_Par = Ident_4;
445 break;
446 case Ident_3: /* executed */
447 *Enum_Ref_Par = Ident_2;
448 break;
449 case Ident_4: break;
450 case Ident_5:
451 *Enum_Ref_Par = Ident_3;
452 break;
453 } /* switch */
454 } /* Proc_6 */
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 */
467 One_Fifty Int_Loc;
469 Int_Loc = Int_1_Par_Val + 2;
470 *Int_Par_Ref = Int_2_Par_Val + Int_Loc;
471 } /* Proc_7 */
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 /*********************************************************************/
476 /* executed once */
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];
491 Int_Glob = 5;
492 } /* Proc_8 */
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;
507 Ch_2_Loc = Ch_1_Loc;
508 if (Ch_2_Loc != Ch_2_Par_Val)
509 /* then, executed */
510 return (Ident_1);
511 else /* not executed */
513 Ch_1_Glob = Ch_1_Loc;
514 return (Ident_2);
516 } /* Func_1 */
519 Boolean Func_2 (Str_30 Str_1_Par_Ref, Str_30 Str_2_Par_Ref)
520 /*************************************************/
521 /* executed once */
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;
529 Int_Loc = 2;
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)
533 /* then, executed */
535 Ch_Loc = 'A';
536 Int_Loc += 1;
537 } /* if, while */
538 if (Ch_Loc >= 'W' && Ch_Loc < 'Z')
539 /* then, not executed */
540 Int_Loc = 7;
541 if (Ch_Loc == 'R')
542 /* then, not executed */
543 return (true);
544 else /* executed */
546 if (strcmp (Str_1_Par_Ref, Str_2_Par_Ref) > 0)
547 /* then, not executed */
549 Int_Loc += 7;
550 Int_Glob = Int_Loc;
551 return (true);
553 else /* executed */
554 return (false);
555 } /* if Ch_Loc */
556 } /* Func_2 */
559 Boolean Func_3 (Enumeration Enum_Par_Val)
560 /***************************/
561 /* executed once */
562 /* Enum_Par_Val == Ident_3 */
564 Enumeration Enum_Loc;
566 Enum_Loc = Enum_Par_Val;
567 if (Enum_Loc == Ident_3)
568 /* then, executed */
569 return (true);
570 else /* not executed */
571 return (false);
572 } /* Func_3 */
574 void init(void)
578 unsigned int clock(void)
580 return(0);
583 #if !defined(PORT_HOST)
584 int putchar(int c)
586 return(c);
588 #endif
590 #else
591 void testDhrystone(void)
594 #endif