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