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