• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1#! /bin/sh
2# This is a shell archive, meaning:
3# 1. Remove everything above the #! /bin/sh line.
4# 2. Save the resulting text in a file.
5# 3. Execute the file with /bin/sh (not csh) to create:
6#        Rationale
7#        dhry.h
8#        dhry_1.c
9#        dhry_2.c
10# This archive created: Wed Jul  6 16:50:06 1988
11export PATH; PATH=/bin:/usr/bin:$PATH
12if test -f 'Rationale'
13then
14        echo shar: "will not over-write existing file 'Rationale'"
15else
16sed 's/^X//' << \SHAR_EOF > 'Rationale'
17XDhrystone Benchmark: Rationale for Version 2 and Measurement Rules
18X
19X                 Reinhold P. Weicker
20X                 Siemens AG, E STE 35
21X                 Postfach 3240
22X                 D-8520 Erlangen
23X                 Germany (West)
24X
25X
26X
27X
28XThe Dhrystone benchmark program [1] has become a popular benchmark  for
29XCPU/compiler  performance  measurement,  in  particular  in the area of
30Xminicomputers, workstations, PC's and  microprocesors.   It  apparently
31Xsatisfies a need for an easy-to-use integer benchmark; it gives a first
32Xperformance indication which  is  more  meaningful  than  MIPS  numbers
33Xwhich,  in  their  literal  meaning  (million instructions per second),
34Xcannot be used across different instruction sets (e.g. RISC vs.  CISC).
35XWith  the  increasing  use  of  the  benchmark,  it  seems necessary to
36Xreconsider the benchmark and to check whether it can still fulfill this
37Xfunction.   Version  2  of  Dhrystone  is  the  result  of  such  a re-
38Xevaluation, it has been made for two reasons:
39X
40Xo Dhrystone has been published in Ada [1], and Versions in Ada,  Pascal
41X  and  C  have  been  distributed  by Reinhold Weicker via floppy disk.
42X  However, the version that was used most often  for  benchmarking  has
43X  been  the version made by Rick Richardson by another translation from
44X  the Ada version into the C programming language, this  has  been  the
45X  version distributed via the UNIX network Usenet [2].
46X
47X  There is an obvious need for a common C version of Dhrystone, since C
48X  is  at  present  the most popular system programming language for the
49X  class of systems (microcomputers, minicomputers, workstations)  where
50X  Dhrystone  is  used  most.  There should be, as far as possible, only
51X  one C version of Dhrystone such that results can be compared  without
52X  restrictions.  In  the  past,  the  C  versions  distributed  by Rick
53X  Richardson (Version 1.1) and by Reinhold Weicker  had  small  (though
54X  not significant) differences.
55X
56X  Together with the new C version, the Ada  and  Pascal  versions  have
57X  been updated as well.
58X
59Xo As far as it is possible without changes to the Dhrystone statistics,
60X  optimizing  compilers  should  be prevented from removing significant
61X  statements.  It has turned out in the past that optimizing  compilers
62X  suppressed  code  generation  for  too many statements (by "dead code
63X  removal" or "dead variable  elimination").   This  has  lead  to  the
64X  danger  that  benchmarking results obtained by a naive application of
65X  Dhrystone - without inspection of the code that was generated - could
66X  become meaningless.
67X
68XThe overall policiy for version 2 has been  that  the  distribution  of
69Xstatements,  operand types and operand locality described in [1] should
70Xremain  unchanged  as  much  as  possible.   (Very  few  changes   were
71Xnecessary;  their  impact  should  be  negligible.)  Also, the order of
72Xstatements should  remain  unchanged.  Although  I  am  aware  of  some
73Xcritical  remarks on the benchmark - I agree with several of them - and
74Xknow some suggestions for improvement, I  didn't  want  to  change  the
75Xbenchmark  into  something  different  from  what  has  become known as
76X"Dhrystone"; the confusion generated by such a  change  would  probably
77Xoutweight  the  benefits. If I were to write a new benchmark program, I
78Xwouldn't give it the name "Dhrystone" since this  denotes  the  program
79Xpublished in [1].  However, I do recognize the need for a larger number
80Xof representative programs that can be used as benchmarks; users should
81Xalways be encouraged to use more than just one benchmark.
82X
83XThe  new  versions  (version  2.1  for  C,  Pascal  and  Ada)  will  be
84Xdistributed  as  widely as possible.  (Version 2.1 differs from version
85X2.0 distributed via the UNIX Network Usenet in March 1988 only in a few
86Xcorrections  for  minor  deficiencies  found  by users of version 2.0.)
87XReaders who want to use the benchmark for their  own  measurements  can
88Xobtain  a copy in machine-readable form on floppy disk (MS-DOS or XENIX
89Xformat) from the author.
90X
91X
92XIn general, version 2 follows - in the parts that are  significant  for
93Xperformance  measurement,  i.e.   within  the  measurement  loop  - the
94Xpublished (Ada) version and  the  C  versions  previously  distributed.
95XWhere  the  versions  distributed  by  Rick Richardson [2] and Reinhold
96XWeicker have been different, it  follows  the  version  distributed  by
97XReinhold  Weicker.  (However,  the  differences have been so small that
98Xtheir impact on execution time in all likelihood has been  negligible.)
99XThe  initialization  and  UNIX  instrumentation  part  - which had been
100Xomitted in [1] - follows mostly  the  ideas  of  Rick  Richardson  [2].
101XHowever,  any changes in the initialization part and in the printing of
102Xthe result have no impact on performance  measurement  since  they  are
103Xoutside  the  measaurement  loop.   As a concession to older compilers,
104Xnames have been made unique within the first 8  characters  for  the  C
105Xversion.
106X
107XThe original publication of Dhrystone did not  contain  any  statements
108Xfor  time  measurement  since  they  are  necessarily system-dependent.
109XHowever, it turned out that it is not enough just to inclose  the  main
110Xprocedure of Dhrystone in a loop and to measure the execution time.  If
111Xthe variables that are computed are not  used  somehow,  there  is  the
112Xdanger  that  the  compiler  considers  them  as  "dead  variables" and
113Xsuppresses code generation for a part of the statements.  Therefore  in
114Xversion  2  all  variables  of  "main"  are  printed  at the end of the
115Xprogram. This  also  permits  some  plausibility  control  for  correct
116Xexecution of the benchmark.
117X
118XAt several places in the benchmark, code has been added,  but  only  in
119Xbranches  that  are  not  executed.  The  intention  is that optimizing
120Xcompilers should be prevented from moving code out of  the  measurement
121Xloop,  or  from  removing code altogether. Statements that are executed
122Xhave been changed in very few places only.  In these  cases,  only  the
123Xrole  of  some operands has been changed, and it was made sure that the
124Xnumbers  defining  the  "Dhrystone   distribution"   (distribution   of
125Xstatements, operand types and locality) still hold as much as possible.
126XExcept for sophisticated  optimizing  compilers,  execution  times  for
127Xversion 2.1 should be the same as for previous versions.
128X
129XBecause of the self-imposed limitation that the order and  distribution
130Xof the executed statements should not be changed, there are still cases
131Xwhere optimizing compilers may not generate code for  some  statements.
132XTo   a   certain  degree,  this  is  unavoidable  for  small  synthetic
133Xbenchmarks.  Users of the benchmark are advised to check code  listings
134Xwhether code is generated for all statements of Dhrystone.
135X
136XContrary to the suggestion in the published paper and  its  realization
137Xin  the  versions  previously  distributed, no attempt has been made to
138Xsubtract the time for the measurement loop overhead. (This  calculation
139Xhas  proven  difficult  to implement in a correct way, and its omission
140Xmakes the program simpler.) However, since the loop check is  now  part
141Xof  the benchmark, this does have an impact - though a very minor one -
142Xon the  distribution  statistics  which  have  been  updated  for  this
143Xversion.
144X
145X
146XIn this section, all changes are described that affect the  measurement
147Xloop and that are not just renamings of variables. All remarks refer to
148Xthe C version; the other language versions have been updated similarly.
149X
150XIn addition to adding the measurement loop and the printout statements,
151Xchanges have been made at the following places:
152X
153Xo In procedure "main", three statements have been  added  in  the  non-
154X  executed "then" part of the statement
155X    if (Enum_Loc == Func_1 (Ch_Index, 'C'))
156X  they are
157X    strcpy (Str_2_Loc, "DHRYSTONE PROGRAM, 3'RD STRING");
158X    Int_2_Loc = Run_Index;
159X    Int_Glob = Run_Index;
160X  The string assignment prevents movement of the  preceding  assignment
161X  to  Str_2_Loc  (5'th statement of "main") out of the measurement loop
162X  (This probably will not happen for the C version, but it  did  happen
163X  with  another  language  and  compiler.)  The assignment to Int_2_Loc
164X  prevents value propagation  for  Int_2_Loc,  and  the  assignment  to
165X  Int_Glob  makes  the  value  of  Int_Glob possibly dependent from the
166X  value of Run_Index.
167X
168Xo In the three arithmetic computations at the end  of  the  measurement
169X  loop  in  "main  ", the role of some variables has been exchanged, to
170X  prevent the division from just cancelling out the  multiplication  as
171X  it  was in [1].  A very smart compiler might have recognized this and
172X  suppressed code generation for the division.
173X
174Xo For Proc_2, no code has been changed, but the values  of  the  actual
175X  parameter have changed due to changes in "main".
176X
177Xo In Proc_4, the second assignment has been changed from
178X    Bool_Loc = Bool_Loc | Bool_Glob;
179X  to
180X    Bool_Glob = Bool_Loc | Bool_Glob;
181X  It now assigns a value to  a  global  variable  instead  of  a  local
182X  variable (Bool_Loc); Bool_Loc would be a "dead variable" which is not
183X  used afterwards.
184X
185Xo In Func_1, the statement
186X    Ch_1_Glob = Ch_1_Loc;
187X  was added in the non-executed "else" part of the "if"  statement,  to
188X  prevent  the  suppression  of  code  generation for the assignment to
189X  Ch_1_Loc.
190X
191Xo In Func_2, the second character comparison statement has been changed
192X  to
193X    if (Ch_Loc == 'R')
194X  ('R' instead of 'X') because a comparison with 'X' is implied in  the
195X  preceding "if" statement.
196X
197X  Also in Func_2, the statement
198X    Int_Glob = Int_Loc;
199X  has been added in the non-executed part of the last  "if"  statement,
200X  in order to prevent Int_Loc from becoming a dead variable.
201X
202Xo In Func_3, a non-executed "else" part has  been  added  to  the  "if"
203X  statement.   While  the  program  would not be incorrect without this
204X  "else" part, it is considered bad programming practice if a  function
205X  can be left without a return value.
206X
207X  To compensate for this change, the (non-executed) "else" part in  the
208X  "if" statement of Proc_3 was removed.
209X
210XThe distribution statistics have been changed only by the  addition  of
211Xthe  measurement  loop  iteration (1 additional statement, 4 additional
212Xlocal integer operands) and  by  the  change  in  Proc_4  (one  operand
213Xchanged  from  local  to  global).  The  distribution statistics in the
214Xcomment headers have been updated accordingly.
215X
216X
217XThe string operations (string assignment and  string  comparison)  have
218Xnot  been  changed,  to  keep  the program consistent with the original
219Xversion.
220X
221XThere has been some  concern  that  the  string  operations  are  over-
222Xrepresented  in  the  program,  and that execution time is dominated by
223Xthese  operations.   This  was  true  in  particular  when   optimizing
224Xcompilers  removed  too much code in the main part of the program, this
225Xshould have been mitigated in version 2.
226X
227XIt should be noted that this is a language-dependent issue:   Dhrystone
228Xwas  first published in Ada, and with Ada or Pascal semantics, the time
229Xspent in the string operations is,  at  least  in  all  implementations
230Xknown  to  me, considerably smaller.  In Ada and Pascal, assignment and
231Xcomparison of strings are operators defined in the  language,  and  the
232Xupper  bounds of the strings occuring in Dhrystone are part of the type
233Xinformation known at compilation time.   The  compilers  can  therefore
234Xgenerate efficient inline code.  In C, string assignemt and comparisons
235Xare not part  of  the  language,  so  the  string  operations  must  be
236Xexpressed  in  terms  of the C library functions "strcpy" and "strcmp".
237X(ANSI  C  allows  an  implementation  to  use  inline  code  for  these
238Xfunctions.)   In addition to the overhead caused by additional function
239Xcalls, these functions are defined for  null-terminated  strings  where
240Xthe  length  of  the  strings  is  not  known  at compilation time; the
241Xfunction has to check every byte for  the  termination  condition  (the
242Xnull byte).
243X
244XObviously, a C library which includes efficiently  coded  "strcpy"  and
245X"strcmp"  functions  helps to obtain good Dhrystone results. However, I
246Xdon't think that this is unfair since string functions do  occur  quite
247Xfrequently  in real programs (editors, command interpreters, etc.).  If
248Xthe strings functions are  implemented  efficiently,  this  helps  real
249Xprograms as well as benchmark programs.
250X
251XI admit that the string comparison in Dhrystone terminates later (after
252Xscanning  20 characters) than most string comparisons in real programs.
253XFor consistency with  the  original  benchmark,  I  didn't  change  the
254Xprogram despite this weakness.
255X
256X
257XWhen Dhrystone is used, the following "ground rules" apply:
258X
259Xo Separate compilation (Ada and C versions)
260X
261X  As  mentioned  in  [1],  Dhrystone  was  written  to  reflect  actual
262X  programming  practice  in  systems  programming.   The  division into
263X  several compilation units (5 in the Ada version, 2 in the C  version)
264X  is  intended, as is the distribution of inter-module and intra-module
265X  subprogram  calls.   Although  on  many  systems  there  will  be  no
266X  difference  in  execution  time  to  a  Dhrystone  version  where all
267X  compilation units are merged into one file, the rule is that separate
268X  compilation  should  be used.  The intention is that real programming
269X  practice, where programs consist of  several  independently  compiled
270X  units, should be reflected.  This also has implies that the compiler,
271X  while compiling one  unit,  has  no  information  about  the  use  of
272X  variables,  register  allocation  etc.  occuring in other compilation
273X  units.  Although in real life  compilation  units  will  probably  be
274X  larger,  the  intention is that these effects of separate compilation
275X  are modeled in Dhrystone.
276X
277X  A few  language  systems  have  post-linkage  optimization  available
278X  (e.g.,  final  register allocation is performed after linkage).  This
279X  is a borderline case: Post-linkage optimization  involves  additional
280X  program  preparation time (although not as much as compilation in one
281X  unit) which may prevent its general use in practical programming.   I
282X  think that since it defeats the intentions given above, it should not
283X  be used for Dhrystone.
284X
285X  Unfortunately, ISO/ANSI Pascal does not contain language features for
286X  separate  compilation.   Although  most  commercial  Pascal compilers
287X  provide separate compilation in  some  way,  we  cannot  use  it  for
288X  Dhrystone  since such a version would not be portable.  Therefore, no
289X  attempt has been made  to  provide  a  Pascal  version  with  several
290X  compilation units.
291X
292Xo No procedure merging
293X
294X  Although  Dhrystone  contains  some  very  short   procedures   where
295X  execution  would  benefit  from  procedure  merging  (inlining, macro
296X  expansion of procedures), procedure merging is not to be  used.   The
297X  reason is that the percentage of procedure and function calls is part
298X  of the "Dhrystone distribution" of statements contained in [1].  This
299X  restriction  does  not hold for the string functions of the C version
300X  since ANSI C allows an implementation to use inline  code  for  these
301X  functions.
302X
303X
304X
305Xo Other optimizations are allowed, but they should be indicated
306X
307X  It is  often  hard  to  draw  an  exact  line  between  "normal  code
308X  generation"  and  "optimization" in compilers: Some compilers perform
309X  operations by default that are invoked in other compilers  only  when
310X  optimization  is explicitly requested.  Also, we cannot avoid that in
311X  benchmarking people try to achieve  results  that  look  as  good  as
312X  possible.   Therefore,  optimizations  performed by compilers - other
313X  than those listed above - are not forbidden when Dhrystone  execution
314X  times  are measured.  Dhrystone is not intended to be non-optimizable
315X  but is intended to be similarly optimizable as normal programs.   For
316X  example,  there  are  several  places  in Dhrystone where performance
317X  benefits from optimizations like  common  subexpression  elimination,
318X  value propagation etc., but normal programs usually also benefit from
319X  these optimizations.  Therefore, no effort was made  to  artificially
320X  prevent  such  optimizations.   However,  measurement  reports should
321X  indicate which compiler  optimization  levels  have  been  used,  and
322X  reporting  results with different levels of compiler optimization for
323X  the same hardware is encouraged.
324X
325Xo Default results are those without "register" declarations (C version)
326X
327X  When Dhrystone results are quoted without  additional  qualification,
328X  they  should  be  understood  as  results obtained without use of the
329X  "register" attribute. Good compilers should be able to make good  use
330X  of  registers  even  without  explicit register declarations ([3], p.
331X  193).
332X
333XOf  course,  for  experimental  purposes,  post-linkage   optimization,
334Xprocedure  merging  and/or  compilation  in  one  unit  can  be done to
335Xdetermine their effects.  However,  Dhrystone  numbers  obtained  under
336Xthese   conditions  should  be  explicitly  marked  as  such;  "normal"
337XDhrystone results should be understood as  results  obtained  following
338Xthe ground rules listed above.
339X
340XIn any case, for serious performance evaluation, users are  advised  to
341Xask  for  code listings and to check them carefully.  In this way, when
342Xresults for different systems  are  compared,  the  reader  can  get  a
343Xfeeling how much performance difference is due to compiler optimization
344Xand how much is due to hardware speed.
345X
346X
347XThe C version 2.1 of Dhrystone has been developed in  cooperation  with
348XRick Richardson (Tinton Falls, NJ), it incorporates many ideas from the
349X"Version 1.1" distributed previously  by  him  over  the  UNIX  network
350XUsenet.  Through  his  activity with Usenet, Rick Richardson has made a
351Xvery valuable contribution to the dissemination of  the  benchmark.   I
352Xalso  thank  Chaim  Benedelac  (National  Semiconductor),  David Ditzel
353X(SUN), Earl Killian and John  Mashey  (MIPS),  Alan  Smith  and  Rafael
354XSaavedra-Barrera  (UC  at  Berkeley)  for  their  help with comments on
355Xearlier versions of the benchmark.
356X
357X
358X[1]
359X   Reinhold P. Weicker:  Dhrystone:  A  Synthetic  Systems  Programming
360X   Benchmark.
361X   Communications of the ACM 27, 10 (Oct. 1984), 1013-1030
362X
363X[2]
364X   Rick Richardson: Dhrystone 1.1 Benchmark Summary (and Program Text)
365X   Informal Distribution via "Usenet", Last Version Known to me:  Sept.
366X   21, 1987
367X
368X[3]
369X   Brian W.  Kernighan  and  Dennis  M.  Ritchie:   The  C  Programming
370X   Language.
371X   Prentice-Hall, Englewood Cliffs (NJ) 1978
372X
373X
374X
375X
376X
377SHAR_EOF
378fi
379if test -f 'dhry.h'
380then
381        echo shar: "will not over-write existing file 'dhry.h'"
382else
383sed 's/^X//' << \SHAR_EOF > 'dhry.h'
384X/*
385X ****************************************************************************
386X *
387X *                   "DHRYSTONE" Benchmark Program
388X *                   -----------------------------
389X *
390X *  Version:    C, Version 2.1
391X *
392X *  File:       dhry.h (part 1 of 3)
393X *
394X *  Date:       May 17, 1988
395X *
396X *  Author:     Reinhold P. Weicker
397X *                      Siemens AG, E STE 35
398X *                      Postfach 3240
399X *                      8520 Erlangen
400X *                      Germany (West)
401X *                              Phone:  [xxx-49]-9131-7-20330
402X *                                      (8-17 Central European Time)
403X *                              Usenet: ..!mcvax!unido!estevax!weicker
404X *
405X *              Original Version (in Ada) published in
406X *              "Communications of the ACM" vol. 27., no. 10 (Oct. 1984),
407X *              pp. 1013 - 1030, together with the statistics
408X *              on which the distribution of statements etc. is based.
409X *
410X *              In this C version, the following C library functions are used:
411X *              - strcpy, strcmp (inside the measurement loop)
412X *              - printf, scanf (outside the measurement loop)
413X *              In addition, Berkeley UNIX system calls "times ()" or "time ()"
414X *              are used for execution time measurement. For measurements
415X *              on other systems, these calls have to be changed.
416X *
417X *  Collection of Results:
418X *              Reinhold Weicker (address see above) and
419X *
420X *              Rick Richardson
421X *              PC Research. Inc.
422X *              94 Apple Orchard Drive
423X *              Tinton Falls, NJ 07724
424X *                      Phone:  (201) 389-8963 (9-17 EST)
425X *                      Usenet: ...!uunet!pcrat!rick
426X *
427X *      Please send results to Rick Richardson and/or Reinhold Weicker.
428X *      Complete information should be given on hardware and software used.
429X *      Hardware information includes: Machine type, CPU, type and size
430X *      of caches; for microprocessors: clock frequency, memory speed
431X *      (number of wait states).
432X *      Software information includes: Compiler (and runtime library)
433X *      manufacturer and version, compilation switches, OS version.
434X *      The Operating System version may give an indication about the
435X *      compiler; Dhrystone itself performs no OS calls in the measurement loop.
436X *
437X *      The complete output generated by the program should be mailed
438X *      such that at least some checks for correctness can be made.
439X *
440X ***************************************************************************
441X *
442X *  History:    This version C/2.1 has been made for two reasons:
443X *
444X *              1) There is an obvious need for a common C version of
445X *              Dhrystone, since C is at present the most popular system
446X *              programming language for the class of processors
447X *              (microcomputers, minicomputers) where Dhrystone is used most.
448X *              There should be, as far as possible, only one C version of
449X *              Dhrystone such that results can be compared without
450X *              restrictions. In the past, the C versions distributed
451X *              by Rick Richardson (Version 1.1) and by Reinhold Weicker
452X *              had small (though not significant) differences.
453X *
454X *              2) As far as it is possible without changes to the Dhrystone
455X *              statistics, optimizing compilers should be prevented from
456X *              removing significant statements.
457X *
458X *              This C version has been developed in cooperation with
459X *              Rick Richardson (Tinton Falls, NJ), it incorporates many
460X *              ideas from the "Version 1.1" distributed previously by
461X *              him over the UNIX network Usenet.
462X *              I also thank Chaim Benedelac (National Semiconductor),
463X *              David Ditzel (SUN), Earl Killian and John Mashey (MIPS),
464X *              Alan Smith and Rafael Saavedra-Barrera (UC at Berkeley)
465X *              for their help with comments on earlier versions of the
466X *              benchmark.
467X *
468X *  Changes:    In the initialization part, this version follows mostly
469X *              Rick Richardson's version distributed via Usenet, not the
470X *              version distributed earlier via floppy disk by Reinhold Weicker.
471X *              As a concession to older compilers, names have been made
472X *              unique within the first 8 characters.
473X *              Inside the measurement loop, this version follows the
474X *              version previously distributed by Reinhold Weicker.
475X *
476X *              At several places in the benchmark, code has been added,
477X *              but within the measurement loop only in branches that
478X *              are not executed. The intention is that optimizing compilers
479X *              should be prevented from moving code out of the measurement
480X *              loop, or from removing code altogether. Since the statements
481X *              that are executed within the measurement loop have NOT been
482X *              changed, the numbers defining the "Dhrystone distribution"
483X *              (distribution of statements, operand types and locality)
484X *              still hold. Except for sophisticated optimizing compilers,
485X *              execution times for this version should be the same as
486X *              for previous versions.
487X *
488X *              Since it has proven difficult to subtract the time for the
489X *              measurement loop overhead in a correct way, the loop check
490X *              has been made a part of the benchmark. This does have
491X *              an impact - though a very minor one - on the distribution
492X *              statistics which have been updated for this version.
493X *
494X *              All changes within the measurement loop are described
495X *              and discussed in the companion paper "Rationale for
496X *              Dhrystone version 2".
497X *
498X *              Because of the self-imposed limitation that the order and
499X *              distribution of the executed statements should not be
500X *              changed, there are still cases where optimizing compilers
501X *              may not generate code for some statements. To a certain
502X *              degree, this is unavoidable for small synthetic benchmarks.
503X *              Users of the benchmark are advised to check code listings
504X *              whether code is generated for all statements of Dhrystone.
505X *
506X *              Version 2.1 is identical to version 2.0 distributed via
507X *              the UNIX network Usenet in March 1988 except that it corrects
508X *              some minor deficiencies that were found by users of version 2.0.
509X *              The following corrections have been made in the C version:
510X *              - The assignment to Number_Of_Runs was changed
511X *              - The constant Too_Small_Time was changed
512X *              - An "else" part was added to the "if" statement in Func_3;
513X *                for compensation, an "else" part was removed in Proc_3
514X *              - Shorter file names are used
515X *
516X ***************************************************************************
517X *
518X * Defines:     The following "Defines" are possible:
519X *              -DREG=register          (default: Not defined)
520X *                      As an approximation to what an average C programmer
521X *                      might do, the "register" storage class is applied
522X *                      (if enabled by -DREG=register)
523X *                      - for local variables, if they are used (dynamically)
524X *                        five or more times
525X *                      - for parameters if they are used (dynamically)
526X *                        six or more times
527X *                      Note that an optimal "register" strategy is
528X *                      compiler-dependent, and that "register" declarations
529X *                      do not necessarily lead to faster execution.
530X *              -DNOSTRUCTASSIGN        (default: Not defined)
531X *                      Define if the C compiler does not support
532X *                      assignment of structures.
533X *              -DNOENUMS               (default: Not defined)
534X *                      Define if the C compiler does not support
535X *                      enumeration types.
536X *              -DTIMES                 (default)
537X *              -DTIME
538X *                      The "times" function of UNIX (returning process times)
539X *                      or the "time" function (returning wallclock time)
540X *                      is used for measurement.
541X *                      For single user machines, "time ()" is adequate. For
542X *                      multi-user machines where you cannot get single-user
543X *                      access, use the "times ()" function. If you have
544X *                      neither, use a stopwatch in the dead of night.
545X *                      "printf"s are provided marking the points "Start Timer"
546X *                      and "Stop Timer". DO NOT use the UNIX "time(1)"
547X *                      command, as this will measure the total time to
548X *                      run this program, which will (erroneously) include
549X *                      the time to allocate storage (malloc) and to perform
550X *                      the initialization.
551X *              -DHZ=nnn
552X *                      In Berkeley UNIX, the function "times" returns process
553X *                      time in 1/HZ seconds, with HZ = 60 for most systems.
554X *                      CHECK YOUR SYSTEM DESCRIPTION BEFORE YOU JUST APPLY
555X *                      A VALUE.
556X *
557X ***************************************************************************
558X *
559X *  Compilation model and measurement (IMPORTANT):
560X *
561X *  This C version of Dhrystone consists of three files:
562X *  - dhry.h (this file, containing global definitions and comments)
563X *  - dhry_1.c (containing the code corresponding to Ada package Pack_1)
564X *  - dhry_2.c (containing the code corresponding to Ada package Pack_2)
565X *
566X *  The following "ground rules" apply for measurements:
567X *  - Separate compilation
568X *  - No procedure merging
569X *  - Otherwise, compiler optimizations are allowed but should be indicated
570X *  - Default results are those without register declarations
571X *  See the companion paper "Rationale for Dhrystone Version 2" for a more
572X *  detailed discussion of these ground rules.
573X *
574X *  For 16-Bit processors (e.g. 80186, 80286), times for all compilation
575X *  models ("small", "medium", "large" etc.) should be given if possible,
576X *  together with a definition of these models for the compiler system used.
577X *
578X **************************************************************************
579X *
580X *  Dhrystone (C version) statistics:
581X *
582X *  [Comment from the first distribution, updated for version 2.
583X *   Note that because of language differences, the numbers are slightly
584X *   different from the Ada version.]
585X *
586X *  The following program contains statements of a high level programming
587X *  language (here: C) in a distribution considered representative:
588X *
589X *    assignments                  52 (51.0 %)
590X *    control statements           33 (32.4 %)
591X *    procedure, function calls    17 (16.7 %)
592X *
593X *  103 statements are dynamically executed. The program is balanced with
594X *  respect to the three aspects:
595X *
596X *    - statement type
597X *    - operand type
598X *    - operand locality
599X *         operand global, local, parameter, or constant.
600X *
601X *  The combination of these three aspects is balanced only approximately.
602X *
603X *  1. Statement Type:
604X *  -----------------             number
605X *
606X *     V1 = V2                     9
607X *       (incl. V1 = F(..)
608X *     V = Constant               12
609X *     Assignment,                 7
610X *       with array element
611X *     Assignment,                 6
612X *       with record component
613X *                                --
614X *                                34       34
615X *
616X *     X = Y +|-|"&&"|"|" Z        5
617X *     X = Y +|-|"==" Constant     6
618X *     X = X +|- 1                 3
619X *     X = Y *|/ Z                 2
620X *     X = Expression,             1
621X *           two operators
622X *     X = Expression,             1
623X *           three operators
624X *                                --
625X *                                18       18
626X *
627X *     if ....                    14
628X *       with "else"      7
629X *       without "else"   7
630X *           executed        3
631X *           not executed    4
632X *     for ...                     7  |  counted every time
633X *     while ...                   4  |  the loop condition
634X *     do ... while                1  |  is evaluated
635X *     switch ...                  1
636X *     break                       1
637X *     declaration with            1
638X *       initialization
639X *                                --
640X *                                34       34
641X *
642X *     P (...)  procedure call    11
643X *       user procedure      10
644X *       library procedure    1
645X *     X = F (...)
646X *             function  call      6
647X *       user function        5
648X *       library function     1
649X *                                --
650X *                                17       17
651X *                                        ---
652X *                                        103
653X *
654X *    The average number of parameters in procedure or function calls
655X *    is 1.82 (not counting the function values as implicit parameters).
656X *
657X *
658X *  2. Operators
659X *  ------------
660X *                          number    approximate
661X *                                    percentage
662X *
663X *    Arithmetic             32          50.8
664X *
665X *       +                     21          33.3
666X *       -                      7          11.1
667X *       *                      3           4.8
668X *       / (int div)            1           1.6
669X *
670X *    Comparison             27           42.8
671X *
672X *       ==                     9           14.3
673X *       /=                     4            6.3
674X *       >                      1            1.6
675X *       <                      3            4.8
676X *       >=                     1            1.6
677X *       <=                     9           14.3
678X *
679X *    Logic                   4            6.3
680X *
681X *       && (AND-THEN)          1            1.6
682X *       |  (OR)                1            1.6
683X *       !  (NOT)               2            3.2
684X *
685X *                           --          -----
686X *                           63          100.1
687X *
688X *
689X *  3. Operand Type (counted once per operand reference):
690X *  ---------------
691X *                          number    approximate
692X *                                    percentage
693X *
694X *     Integer               175        72.3 %
695X *     Character              45        18.6 %
696X *     Pointer                12         5.0 %
697X *     String30                6         2.5 %
698X *     Array                   2         0.8 %
699X *     Record                  2         0.8 %
700X *                           ---       -------
701X *                           242       100.0 %
702X *
703X *  When there is an access path leading to the final operand (e.g. a record
704X *  component), only the final data type on the access path is counted.
705X *
706X *
707X *  4. Operand Locality:
708X *  -------------------
709X *                                number    approximate
710X *                                          percentage
711X *
712X *     local variable              114        47.1 %
713X *     global variable              22         9.1 %
714X *     parameter                    45        18.6 %
715X *        value                        23         9.5 %
716X *        reference                    22         9.1 %
717X *     function result               6         2.5 %
718X *     constant                     55        22.7 %
719X *                                 ---       -------
720X *                                 242       100.0 %
721X *
722X *
723X *  The program does not compute anything meaningful, but it is syntactically
724X *  and semantically correct. All variables have a value assigned to them
725X *  before they are used as a source operand.
726X *
727X *  There has been no explicit effort to account for the effects of a
728X *  cache, or to balance the use of long or short displacements for code or
729X *  data.
730X *
731X ***************************************************************************
732X */
733X
734X/* Compiler and system dependent definitions: */
735X
736X#ifndef TIME
737X#ifndef TIMES
738X#define TIMES
739X#endif
740X#endif
741X                /* Use times(2) time function unless    */
742X                /* explicitly defined otherwise         */
743X
744X#ifdef MSC_CLOCK
745X#undef HZ
746X#undef TIMES
747X#include <time.h>
748X#define HZ        CLK_TCK
749X#endif
750X                /* Use Microsoft C hi-res clock */
751X
752X#ifdef TIMES
753X#include <sys/types.h>
754X#include <sys/times.h>
755X                /* for "times" */
756X#endif
757X
758X#define Mic_secs_Per_Second     1000000.0
759X                /* Berkeley UNIX C returns process times in seconds/HZ */
760X
761X#ifdef  NOSTRUCTASSIGN
762X#define structassign(d, s)      memcpy(&(d), &(s), sizeof(d))
763X#else
764X#define structassign(d, s)      d = s
765X#endif
766X
767X#ifdef  NOENUM
768X#define Ident_1 0
769X#define Ident_2 1
770X#define Ident_3 2
771X#define Ident_4 3
772X#define Ident_5 4
773X  typedef int   Enumeration;
774X#else
775X  typedef       enum    {Ident_1, Ident_2, Ident_3, Ident_4, Ident_5}
776X                Enumeration;
777X#endif
778X        /* for boolean and enumeration types in Ada, Pascal */
779X
780X/* General definitions: */
781X
782X#include <stdio.h>
783X                /* for strcpy, strcmp */
784X
785X#define Null 0
786X                /* Value of a Null pointer */
787X#define true  1
788X#define false 0
789X
790Xtypedef int     One_Thirty;
791Xtypedef int     One_Fifty;
792Xtypedef char    Capital_Letter;
793Xtypedef int     Boolean;
794Xtypedef char    Str_30 [31];
795Xtypedef int     Arr_1_Dim [50];
796Xtypedef int     Arr_2_Dim [50] [50];
797X
798Xtypedef struct record
799X    {
800X    struct record *Ptr_Comp;
801X    Enumeration    Discr;
802X    union {
803X          struct {
804X                  Enumeration Enum_Comp;
805X                  int         Int_Comp;
806X                  char        Str_Comp [31];
807X                  } var_1;
808X          struct {
809X                  Enumeration E_Comp_2;
810X                  char        Str_2_Comp [31];
811X                  } var_2;
812X          struct {
813X                  char        Ch_1_Comp;
814X                  char        Ch_2_Comp;
815X                  } var_3;
816X          } variant;
817X      } Rec_Type, *Rec_Pointer;
818X
819X
820SHAR_EOF
821fi
822if test -f 'dhry_1.c'
823then
824        echo shar: "will not over-write existing file 'dhry_1.c'"
825else
826sed 's/^X//' << \SHAR_EOF > 'dhry_1.c'
827X/*
828X ****************************************************************************
829X *
830X *                   "DHRYSTONE" Benchmark Program
831X *                   -----------------------------
832X *
833X *  Version:    C, Version 2.1
834X *
835X *  File:       dhry_1.c (part 2 of 3)
836X *
837X *  Date:       May 17, 1988
838X *
839X *  Author:     Reinhold P. Weicker
840X *
841X ****************************************************************************
842X */
843X
844X#include "dhry.h"
845X
846X/* Global Variables: */
847X
848XRec_Pointer     Ptr_Glob,
849X                Next_Ptr_Glob;
850Xint             Int_Glob;
851XBoolean         Bool_Glob;
852Xchar            Ch_1_Glob,
853X                Ch_2_Glob;
854Xint             Arr_1_Glob [50];
855Xint             Arr_2_Glob [50] [50];
856X
857Xextern char     *malloc ();
858XEnumeration     Func_1 ();
859X  /* forward declaration necessary since Enumeration may not simply be int */
860X
861X#ifndef REG
862X        Boolean Reg = false;
863X#define REG
864X        /* REG becomes defined as empty */
865X        /* i.e. no register variables   */
866X#else
867X        Boolean Reg = true;
868X#endif
869X
870X/* variables for time measurement: */
871X
872X#ifdef TIMES
873Xstruct tms      time_info;
874Xextern  int     times ();
875X                /* see library function "times" */
876X#define Too_Small_Time (2*HZ)
877X                /* Measurements should last at least about 2 seconds */
878X#endif
879X#ifdef TIME
880Xextern long     time();
881X                /* see library function "time"  */
882X#define Too_Small_Time 2
883X                /* Measurements should last at least 2 seconds */
884X#endif
885X#ifdef MSC_CLOCK
886Xextern clock_t        clock();
887X#define Too_Small_Time (2*HZ)
888X#endif
889X
890Xlong            Begin_Time,
891X                End_Time,
892X                User_Time;
893Xfloat           Microseconds,
894X                Dhrystones_Per_Second;
895X
896X/* end of variables for time measurement */
897X
898X
899Xmain ()
900X/*****/
901X
902X  /* main program, corresponds to procedures        */
903X  /* Main and Proc_0 in the Ada version             */
904X{
905X        One_Fifty       Int_1_Loc;
906X  REG   One_Fifty       Int_2_Loc;
907X        One_Fifty       Int_3_Loc;
908X  REG   char            Ch_Index;
909X        Enumeration     Enum_Loc;
910X        Str_30          Str_1_Loc;
911X        Str_30          Str_2_Loc;
912X  REG   int             Run_Index;
913X  REG   int             Number_Of_Runs;
914X
915X  /* Initializations */
916X
917X  Next_Ptr_Glob = (Rec_Pointer) malloc (sizeof (Rec_Type));
918X  Ptr_Glob = (Rec_Pointer) malloc (sizeof (Rec_Type));
919X
920X  Ptr_Glob->Ptr_Comp                    = Next_Ptr_Glob;
921X  Ptr_Glob->Discr                       = Ident_1;
922X  Ptr_Glob->variant.var_1.Enum_Comp     = Ident_3;
923X  Ptr_Glob->variant.var_1.Int_Comp      = 40;
924X  strcpy (Ptr_Glob->variant.var_1.Str_Comp,
925X          "DHRYSTONE PROGRAM, SOME STRING");
926X  strcpy (Str_1_Loc, "DHRYSTONE PROGRAM, 1'ST STRING");
927X
928X  Arr_2_Glob [8][7] = 10;
929X        /* Was missing in published program. Without this statement,    */
930X        /* Arr_2_Glob [8][7] would have an undefined value.             */
931X        /* Warning: With 16-Bit processors and Number_Of_Runs > 32000,  */
932X        /* overflow may occur for this array element.                   */
933X
934X  printf ("\n");
935X  printf ("Dhrystone Benchmark, Version 2.1 (Language: C)\n");
936X  printf ("\n");
937X  if (Reg)
938X  {
939X    printf ("Program compiled with 'register' attribute\n");
940X    printf ("\n");
941X  }
942X  else
943X  {
944X    printf ("Program compiled without 'register' attribute\n");
945X    printf ("\n");
946X  }
947X  printf ("Please give the number of runs through the benchmark: ");
948X  {
949X    int n;
950X    scanf ("%d", &n);
951X    Number_Of_Runs = n;
952X  }
953X  printf ("\n");
954X
955X  printf ("Execution starts, %d runs through Dhrystone\n", Number_Of_Runs);
956X
957X  /***************/
958X  /* Start timer */
959X  /***************/
960X
961X#ifdef TIMES
962X  times (&time_info);
963X  Begin_Time = (long) time_info.tms_utime;
964X#endif
965X#ifdef TIME
966X  Begin_Time = time ( (long *) 0);
967X#endif
968X#ifdef MSC_CLOCK
969X  Begin_Time = clock();
970X#endif
971X
972X  for (Run_Index = 1; Run_Index <= Number_Of_Runs; ++Run_Index)
973X  {
974X
975X    Proc_5();
976X    Proc_4();
977X      /* Ch_1_Glob == 'A', Ch_2_Glob == 'B', Bool_Glob == true */
978X    Int_1_Loc = 2;
979X    Int_2_Loc = 3;
980X    strcpy (Str_2_Loc, "DHRYSTONE PROGRAM, 2'ND STRING");
981X    Enum_Loc = Ident_2;
982X    Bool_Glob = ! Func_2 (Str_1_Loc, Str_2_Loc);
983X      /* Bool_Glob == 1 */
984X    while (Int_1_Loc < Int_2_Loc)  /* loop body executed once */
985X    {
986X      Int_3_Loc = 5 * Int_1_Loc - Int_2_Loc;
987X        /* Int_3_Loc == 7 */
988X      Proc_7 (Int_1_Loc, Int_2_Loc, &Int_3_Loc);
989X        /* Int_3_Loc == 7 */
990X      Int_1_Loc += 1;
991X    } /* while */
992X      /* Int_1_Loc == 3, Int_2_Loc == 3, Int_3_Loc == 7 */
993X    Proc_8 (Arr_1_Glob, Arr_2_Glob, Int_1_Loc, Int_3_Loc);
994X      /* Int_Glob == 5 */
995X    Proc_1 (Ptr_Glob);
996X    for (Ch_Index = 'A'; Ch_Index <= Ch_2_Glob; ++Ch_Index)
997X                             /* loop body executed twice */
998X    {
999X      if (Enum_Loc == Func_1 (Ch_Index, 'C'))
1000X          /* then, not executed */
1001X        {
1002X        Proc_6 (Ident_1, &Enum_Loc);
1003X        strcpy (Str_2_Loc, "DHRYSTONE PROGRAM, 3'RD STRING");
1004X        Int_2_Loc = Run_Index;
1005X        Int_Glob = Run_Index;
1006X        }
1007X    }
1008X      /* Int_1_Loc == 3, Int_2_Loc == 3, Int_3_Loc == 7 */
1009X    Int_2_Loc = Int_2_Loc * Int_1_Loc;
1010X    Int_1_Loc = Int_2_Loc / Int_3_Loc;
1011X    Int_2_Loc = 7 * (Int_2_Loc - Int_3_Loc) - Int_1_Loc;
1012X      /* Int_1_Loc == 1, Int_2_Loc == 13, Int_3_Loc == 7 */
1013X    Proc_2 (&Int_1_Loc);
1014X      /* Int_1_Loc == 5 */
1015X
1016X  } /* loop "for Run_Index" */
1017X
1018X  /**************/
1019X  /* Stop timer */
1020X  /**************/
1021X
1022X#ifdef TIMES
1023X  times (&time_info);
1024X  End_Time = (long) time_info.tms_utime;
1025X#endif
1026X#ifdef TIME
1027X  End_Time = time ( (long *) 0);
1028X#endif
1029X#ifdef MSC_CLOCK
1030X  End_Time = clock();
1031X#endif
1032X
1033X  printf ("Execution ends\n");
1034X  printf ("\n");
1035X  printf ("Final values of the variables used in the benchmark:\n");
1036X  printf ("\n");
1037X  printf ("Int_Glob:            %d\n", Int_Glob);
1038X  printf ("        should be:   %d\n", 5);
1039X  printf ("Bool_Glob:           %d\n", Bool_Glob);
1040X  printf ("        should be:   %d\n", 1);
1041X  printf ("Ch_1_Glob:           %c\n", Ch_1_Glob);
1042X  printf ("        should be:   %c\n", 'A');
1043X  printf ("Ch_2_Glob:           %c\n", Ch_2_Glob);
1044X  printf ("        should be:   %c\n", 'B');
1045X  printf ("Arr_1_Glob[8]:       %d\n", Arr_1_Glob[8]);
1046X  printf ("        should be:   %d\n", 7);
1047X  printf ("Arr_2_Glob[8][7]:    %d\n", Arr_2_Glob[8][7]);
1048X  printf ("        should be:   Number_Of_Runs + 10\n");
1049X  printf ("Ptr_Glob->\n");
1050X  printf ("  Ptr_Comp:          %d\n", (int) Ptr_Glob->Ptr_Comp);
1051X  printf ("        should be:   (implementation-dependent)\n");
1052X  printf ("  Discr:             %d\n", Ptr_Glob->Discr);
1053X  printf ("        should be:   %d\n", 0);
1054X  printf ("  Enum_Comp:         %d\n", Ptr_Glob->variant.var_1.Enum_Comp);
1055X  printf ("        should be:   %d\n", 2);
1056X  printf ("  Int_Comp:          %d\n", Ptr_Glob->variant.var_1.Int_Comp);
1057X  printf ("        should be:   %d\n", 17);
1058X  printf ("  Str_Comp:          %s\n", Ptr_Glob->variant.var_1.Str_Comp);
1059X  printf ("        should be:   DHRYSTONE PROGRAM, SOME STRING\n");
1060X  printf ("Next_Ptr_Glob->\n");
1061X  printf ("  Ptr_Comp:          %d\n", (int) Next_Ptr_Glob->Ptr_Comp);
1062X  printf ("        should be:   (implementation-dependent), same as above\n");
1063X  printf ("  Discr:             %d\n", Next_Ptr_Glob->Discr);
1064X  printf ("        should be:   %d\n", 0);
1065X  printf ("  Enum_Comp:         %d\n", Next_Ptr_Glob->variant.var_1.Enum_Comp);
1066X  printf ("        should be:   %d\n", 1);
1067X  printf ("  Int_Comp:          %d\n", Next_Ptr_Glob->variant.var_1.Int_Comp);
1068X  printf ("        should be:   %d\n", 18);
1069X  printf ("  Str_Comp:          %s\n",
1070X                                Next_Ptr_Glob->variant.var_1.Str_Comp);
1071X  printf ("        should be:   DHRYSTONE PROGRAM, SOME STRING\n");
1072X  printf ("Int_1_Loc:           %d\n", Int_1_Loc);
1073X  printf ("        should be:   %d\n", 5);
1074X  printf ("Int_2_Loc:           %d\n", Int_2_Loc);
1075X  printf ("        should be:   %d\n", 13);
1076X  printf ("Int_3_Loc:           %d\n", Int_3_Loc);
1077X  printf ("        should be:   %d\n", 7);
1078X  printf ("Enum_Loc:            %d\n", Enum_Loc);
1079X  printf ("        should be:   %d\n", 1);
1080X  printf ("Str_1_Loc:           %s\n", Str_1_Loc);
1081X  printf ("        should be:   DHRYSTONE PROGRAM, 1'ST STRING\n");
1082X  printf ("Str_2_Loc:           %s\n", Str_2_Loc);
1083X  printf ("        should be:   DHRYSTONE PROGRAM, 2'ND STRING\n");
1084X  printf ("\n");
1085X
1086X  User_Time = End_Time - Begin_Time;
1087X
1088X  if (User_Time < Too_Small_Time)
1089X  {
1090X    printf ("Measured time too small to obtain meaningful results\n");
1091X    printf ("Please increase number of runs\n");
1092X    printf ("\n");
1093X  }
1094X  else
1095X  {
1096X#ifdef TIME
1097X    Microseconds = (float) User_Time * Mic_secs_Per_Second
1098X                        / (float) Number_Of_Runs;
1099X    Dhrystones_Per_Second = (float) Number_Of_Runs / (float) User_Time;
1100X#else
1101X    Microseconds = (float) User_Time * Mic_secs_Per_Second
1102X                        / ((float) HZ * ((float) Number_Of_Runs));
1103X    Dhrystones_Per_Second = ((float) HZ * (float) Number_Of_Runs)
1104X                        / (float) User_Time;
1105X#endif
1106X    printf ("Microseconds for one run through Dhrystone: ");
1107X    printf ("%6.1f \n", Microseconds);
1108X    printf ("Dhrystones per Second:                      ");
1109X    printf ("%6.1f \n", Dhrystones_Per_Second);
1110X    printf ("\n");
1111X  }
1112X
1113X}
1114X
1115X
1116XProc_1 (Ptr_Val_Par)
1117X/******************/
1118X
1119XREG Rec_Pointer Ptr_Val_Par;
1120X    /* executed once */
1121X{
1122X  REG Rec_Pointer Next_Record = Ptr_Val_Par->Ptr_Comp;
1123X                                        /* == Ptr_Glob_Next */
1124X  /* Local variable, initialized with Ptr_Val_Par->Ptr_Comp,    */
1125X  /* corresponds to "rename" in Ada, "with" in Pascal           */
1126X
1127X  structassign (*Ptr_Val_Par->Ptr_Comp, *Ptr_Glob);
1128X  Ptr_Val_Par->variant.var_1.Int_Comp = 5;
1129X  Next_Record->variant.var_1.Int_Comp
1130X        = Ptr_Val_Par->variant.var_1.Int_Comp;
1131X  Next_Record->Ptr_Comp = Ptr_Val_Par->Ptr_Comp;
1132X  Proc_3 (&Next_Record->Ptr_Comp);
1133X    /* Ptr_Val_Par->Ptr_Comp->Ptr_Comp
1134X                        == Ptr_Glob->Ptr_Comp */
1135X  if (Next_Record->Discr == Ident_1)
1136X    /* then, executed */
1137X  {
1138X    Next_Record->variant.var_1.Int_Comp = 6;
1139X    Proc_6 (Ptr_Val_Par->variant.var_1.Enum_Comp,
1140X           &Next_Record->variant.var_1.Enum_Comp);
1141X    Next_Record->Ptr_Comp = Ptr_Glob->Ptr_Comp;
1142X    Proc_7 (Next_Record->variant.var_1.Int_Comp, 10,
1143X           &Next_Record->variant.var_1.Int_Comp);
1144X  }
1145X  else /* not executed */
1146X    structassign (*Ptr_Val_Par, *Ptr_Val_Par->Ptr_Comp);
1147X} /* Proc_1 */
1148X
1149X
1150XProc_2 (Int_Par_Ref)
1151X/******************/
1152X    /* executed once */
1153X    /* *Int_Par_Ref == 1, becomes 4 */
1154X
1155XOne_Fifty   *Int_Par_Ref;
1156X{
1157X  One_Fifty  Int_Loc;
1158X  Enumeration   Enum_Loc;
1159X
1160X  Int_Loc = *Int_Par_Ref + 10;
1161X  do /* executed once */
1162X    if (Ch_1_Glob == 'A')
1163X      /* then, executed */
1164X    {
1165X      Int_Loc -= 1;
1166X      *Int_Par_Ref = Int_Loc - Int_Glob;
1167X      Enum_Loc = Ident_1;
1168X    } /* if */
1169X  while (Enum_Loc != Ident_1); /* true */
1170X} /* Proc_2 */
1171X
1172X
1173XProc_3 (Ptr_Ref_Par)
1174X/******************/
1175X    /* executed once */
1176X    /* Ptr_Ref_Par becomes Ptr_Glob */
1177X
1178XRec_Pointer *Ptr_Ref_Par;
1179X
1180X{
1181X  if (Ptr_Glob != Null)
1182X    /* then, executed */
1183X    *Ptr_Ref_Par = Ptr_Glob->Ptr_Comp;
1184X  Proc_7 (10, Int_Glob, &Ptr_Glob->variant.var_1.Int_Comp);
1185X} /* Proc_3 */
1186X
1187X
1188XProc_4 () /* without parameters */
1189X/*******/
1190X    /* executed once */
1191X{
1192X  Boolean Bool_Loc;
1193X
1194X  Bool_Loc = Ch_1_Glob == 'A';
1195X  Bool_Glob = Bool_Loc | Bool_Glob;
1196X  Ch_2_Glob = 'B';
1197X} /* Proc_4 */
1198X
1199X
1200XProc_5 () /* without parameters */
1201X/*******/
1202X    /* executed once */
1203X{
1204X  Ch_1_Glob = 'A';
1205X  Bool_Glob = false;
1206X} /* Proc_5 */
1207X
1208X
1209X        /* Procedure for the assignment of structures,          */
1210X        /* if the C compiler doesn't support this feature       */
1211X#ifdef  NOSTRUCTASSIGN
1212Xmemcpy (d, s, l)
1213Xregister char   *d;
1214Xregister char   *s;
1215Xregister int    l;
1216X{
1217X        while (l--) *d++ = *s++;
1218X}
1219X#endif
1220X
1221X
1222SHAR_EOF
1223fi
1224if test -f 'dhry_2.c'
1225then
1226        echo shar: "will not over-write existing file 'dhry_2.c'"
1227else
1228sed 's/^X//' << \SHAR_EOF > 'dhry_2.c'
1229X/*
1230X ****************************************************************************
1231X *
1232X *                   "DHRYSTONE" Benchmark Program
1233X *                   -----------------------------
1234X *
1235X *  Version:    C, Version 2.1
1236X *
1237X *  File:       dhry_2.c (part 3 of 3)
1238X *
1239X *  Date:       May 17, 1988
1240X *
1241X *  Author:     Reinhold P. Weicker
1242X *
1243X ****************************************************************************
1244X */
1245X
1246X#include "dhry.h"
1247X
1248X#ifndef REG
1249X#define REG
1250X        /* REG becomes defined as empty */
1251X        /* i.e. no register variables   */
1252X#endif
1253X
1254Xextern  int     Int_Glob;
1255Xextern  char    Ch_1_Glob;
1256X
1257X
1258XProc_6 (Enum_Val_Par, Enum_Ref_Par)
1259X/*********************************/
1260X    /* executed once */
1261X    /* Enum_Val_Par == Ident_3, Enum_Ref_Par becomes Ident_2 */
1262X
1263XEnumeration  Enum_Val_Par;
1264XEnumeration *Enum_Ref_Par;
1265X{
1266X  *Enum_Ref_Par = Enum_Val_Par;
1267X  if (! Func_3 (Enum_Val_Par))
1268X    /* then, not executed */
1269X    *Enum_Ref_Par = Ident_4;
1270X  switch (Enum_Val_Par)
1271X  {
1272X    case Ident_1:
1273X      *Enum_Ref_Par = Ident_1;
1274X      break;
1275X    case Ident_2:
1276X      if (Int_Glob > 100)
1277X        /* then */
1278X      *Enum_Ref_Par = Ident_1;
1279X      else *Enum_Ref_Par = Ident_4;
1280X      break;
1281X    case Ident_3: /* executed */
1282X      *Enum_Ref_Par = Ident_2;
1283X      break;
1284X    case Ident_4: break;
1285X    case Ident_5:
1286X      *Enum_Ref_Par = Ident_3;
1287X      break;
1288X  } /* switch */
1289X} /* Proc_6 */
1290X
1291X
1292XProc_7 (Int_1_Par_Val, Int_2_Par_Val, Int_Par_Ref)
1293X/**********************************************/
1294X    /* executed three times                                      */
1295X    /* first call:      Int_1_Par_Val == 2, Int_2_Par_Val == 3,  */
1296X    /*                  Int_Par_Ref becomes 7                    */
1297X    /* second call:     Int_1_Par_Val == 10, Int_2_Par_Val == 5, */
1298X    /*                  Int_Par_Ref becomes 17                   */
1299X    /* third call:      Int_1_Par_Val == 6, Int_2_Par_Val == 10, */
1300X    /*                  Int_Par_Ref becomes 18                   */
1301XOne_Fifty       Int_1_Par_Val;
1302XOne_Fifty       Int_2_Par_Val;
1303XOne_Fifty      *Int_Par_Ref;
1304X{
1305X  One_Fifty Int_Loc;
1306X
1307X  Int_Loc = Int_1_Par_Val + 2;
1308X  *Int_Par_Ref = Int_2_Par_Val + Int_Loc;
1309X} /* Proc_7 */
1310X
1311X
1312XProc_8 (Arr_1_Par_Ref, Arr_2_Par_Ref, Int_1_Par_Val, Int_2_Par_Val)
1313X/*********************************************************************/
1314X    /* executed once      */
1315X    /* Int_Par_Val_1 == 3 */
1316X    /* Int_Par_Val_2 == 7 */
1317XArr_1_Dim       Arr_1_Par_Ref;
1318XArr_2_Dim       Arr_2_Par_Ref;
1319Xint             Int_1_Par_Val;
1320Xint             Int_2_Par_Val;
1321X{
1322X  REG One_Fifty Int_Index;
1323X  REG One_Fifty Int_Loc;
1324X
1325X  Int_Loc = Int_1_Par_Val + 5;
1326X  Arr_1_Par_Ref [Int_Loc] = Int_2_Par_Val;
1327X  Arr_1_Par_Ref [Int_Loc+1] = Arr_1_Par_Ref [Int_Loc];
1328X  Arr_1_Par_Ref [Int_Loc+30] = Int_Loc;
1329X  for (Int_Index = Int_Loc; Int_Index <= Int_Loc+1; ++Int_Index)
1330X    Arr_2_Par_Ref [Int_Loc] [Int_Index] = Int_Loc;
1331X  Arr_2_Par_Ref [Int_Loc] [Int_Loc-1] += 1;
1332X  Arr_2_Par_Ref [Int_Loc+20] [Int_Loc] = Arr_1_Par_Ref [Int_Loc];
1333X  Int_Glob = 5;
1334X} /* Proc_8 */
1335X
1336X
1337XEnumeration Func_1 (Ch_1_Par_Val, Ch_2_Par_Val)
1338X/*************************************************/
1339X    /* executed three times                                         */
1340X    /* first call:      Ch_1_Par_Val == 'H', Ch_2_Par_Val == 'R'    */
1341X    /* second call:     Ch_1_Par_Val == 'A', Ch_2_Par_Val == 'C'    */
1342X    /* third call:      Ch_1_Par_Val == 'B', Ch_2_Par_Val == 'C'    */
1343X
1344XCapital_Letter   Ch_1_Par_Val;
1345XCapital_Letter   Ch_2_Par_Val;
1346X{
1347X  Capital_Letter        Ch_1_Loc;
1348X  Capital_Letter        Ch_2_Loc;
1349X
1350X  Ch_1_Loc = Ch_1_Par_Val;
1351X  Ch_2_Loc = Ch_1_Loc;
1352X  if (Ch_2_Loc != Ch_2_Par_Val)
1353X    /* then, executed */
1354X    return (Ident_1);
1355X  else  /* not executed */
1356X  {
1357X    Ch_1_Glob = Ch_1_Loc;
1358X    return (Ident_2);
1359X   }
1360X} /* Func_1 */
1361X
1362X
1363XBoolean Func_2 (Str_1_Par_Ref, Str_2_Par_Ref)
1364X/*************************************************/
1365X    /* executed once */
1366X    /* Str_1_Par_Ref == "DHRYSTONE PROGRAM, 1'ST STRING" */
1367X    /* Str_2_Par_Ref == "DHRYSTONE PROGRAM, 2'ND STRING" */
1368X
1369XStr_30  Str_1_Par_Ref;
1370XStr_30  Str_2_Par_Ref;
1371X{
1372X  REG One_Thirty        Int_Loc;
1373X      Capital_Letter    Ch_Loc;
1374X
1375X  Int_Loc = 2;
1376X  while (Int_Loc <= 2) /* loop body executed once */
1377X    if (Func_1 (Str_1_Par_Ref[Int_Loc],
1378X                Str_2_Par_Ref[Int_Loc+1]) == Ident_1)
1379X      /* then, executed */
1380X    {
1381X      Ch_Loc = 'A';
1382X      Int_Loc += 1;
1383X    } /* if, while */
1384X  if (Ch_Loc >= 'W' && Ch_Loc < 'Z')
1385X    /* then, not executed */
1386X    Int_Loc = 7;
1387X  if (Ch_Loc == 'R')
1388X    /* then, not executed */
1389X    return (true);
1390X  else /* executed */
1391X  {
1392X    if (strcmp (Str_1_Par_Ref, Str_2_Par_Ref) > 0)
1393X      /* then, not executed */
1394X    {
1395X      Int_Loc += 7;
1396X      Int_Glob = Int_Loc;
1397X      return (true);
1398X    }
1399X    else /* executed */
1400X      return (false);
1401X  } /* if Ch_Loc */
1402X} /* Func_2 */
1403X
1404X
1405XBoolean Func_3 (Enum_Par_Val)
1406X/***************************/
1407X    /* executed once        */
1408X    /* Enum_Par_Val == Ident_3 */
1409XEnumeration Enum_Par_Val;
1410X{
1411X  Enumeration Enum_Loc;
1412X
1413X  Enum_Loc = Enum_Par_Val;
1414X  if (Enum_Loc == Ident_3)
1415X    /* then, executed */
1416X    return (true);
1417X  else /* not executed */
1418X    return (false);
1419X} /* Func_3 */
1420X
1421SHAR_EOF
1422fi
1423exit 0
1424#        End of shell archive
1425