drystone.pas 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320
  1. PROGRAM Dhrystone( input, output );
  2. uses
  3. timer;
  4. {
  5. * "DHRYSTONE" Benchmark Program
  6. *
  7. * Version: Mod2/1
  8. * Date: 05/03/86
  9. * Author: Reinhold P. Weicker, CACM Vol 27, No 10, 10/84 pg. 1013
  10. * C version translated from ADA by Rick Richardson
  11. * Every method to preserve ADA-likeness has been used,
  12. * at the expense of C-ness.
  13. * Modula-2 version translated from C by Kevin Northover.
  14. * Again every attempt made to avoid distortions of the original.
  15. * Machine Specifics:
  16. * The LOOPS constant is initially set for 50000 loops.
  17. * If you have a machine with large integers and is
  18. * very fast, please change this number to 500000 to
  19. * get better accuracy.
  20. *
  21. **************************************************************************
  22. *
  23. * The following program contains statements of a high-level programming
  24. * language (Modula-2) in a distribution considered representative:
  25. *
  26. * assignments 53%
  27. * control statements 32%
  28. * procedure, function calls 15%
  29. *
  30. * 100 statements are dynamically executed. The program is balanced with
  31. * respect to the three aspects:
  32. * - statement type
  33. * - operand type (for simple data types)
  34. * - operand access
  35. * operand global, local, parameter, or constant.
  36. *
  37. * The combination of these three aspects is balanced only approximately.
  38. *
  39. * The program does not compute anything meaningfull, but it is
  40. * syntactically and semantically correct.
  41. *
  42. }
  43. {$R- range checking off}
  44. CONST
  45. { Set LOOPS to specify how many thousand drystones to perform.
  46. LOOPS = 50 will perforum 50,000 drystones. Choose longer for
  47. better precision and for fast machines.
  48. }
  49. LOOPS = 15000; { Use this for slow or 16 bit machines }
  50. Ident1 = 1;
  51. Ident2 = 2;
  52. Ident3 = 3;
  53. Ident4 = 4;
  54. Ident5 = 5;
  55. type integer = longint;
  56. Type Enumeration = INTEGER;
  57. { TYPE Enumeration = (Ident1, Ident2, Ident3, Ident4, Ident5); }
  58. TYPE OneToThirty = INTEGER;
  59. TYPE OneToFifty = INTEGER;
  60. TYPE CapitalLetter = CHAR;
  61. TYPE String30 = STRING[30]; { ARRAY[0..30] OF CHAR; }
  62. TYPE Array1Dim = ARRAY[0..50] OF INTEGER;
  63. TYPE Array2Dim = ARRAY[0..50,0..50] OF INTEGER;
  64. { TYPE RecordPtr = ^RecordType; }
  65. RecordType = RECORD
  66. PtrComp : integer;
  67. Discr : Enumeration;
  68. EnumComp : Enumeration;
  69. IntComp : OneToFifty;
  70. StringComp : String30;
  71. END;
  72. {
  73. * Package 1
  74. }
  75. VAR
  76. IntGlob : INTEGER;
  77. BoolGlob : BOOLEAN;
  78. Char1Glob : CHAR;
  79. Char2Glob : CHAR ;
  80. Array1Glob : Array1Dim;
  81. Array2Glob : Array2Dim;
  82. MyRec : array[0..2] of RecordType;
  83. { PtrGlb : RecordPtr; }
  84. { PtrGlbNext : RecordPtr; }
  85. Hour, Min, Sec, Hund : word;
  86. TStart, TEnd : real;
  87. CONST
  88. PtrGlb = 1;
  89. PtrGlbNext = 2;
  90. PROCEDURE Proc7(IntParI1, IntParI2 : OneToFifty; VAR IntParOut : OneToFifty);
  91. VAR
  92. IntLoc : OneToFifty;
  93. BEGIN
  94. IntLoc:= IntParI1 + 2;
  95. IntParOut:= IntParI2 + IntLoc;
  96. END ;
  97. PROCEDURE Proc3( var inRecIdx : integer );
  98. BEGIN
  99. IF ( inRecIdx <> 0 ) THEN
  100. inRecIdx := MyRec[PtrGlb].PtrComp
  101. ELSE
  102. IntGlob:= 100;
  103. Proc7( 10, IntGlob, MyRec[PtrGlb].IntComp);
  104. END ;
  105. FUNCTION Func3(EnumParIn : Enumeration) : BOOLEAN;
  106. VAR EnumLoc: Enumeration;
  107. BEGIN
  108. EnumLoc:= EnumParIn;
  109. Func3:= EnumLoc = Ident3;
  110. END ;
  111. PROCEDURE Proc6(EnumParIn : Enumeration; VAR EnumParOut : Enumeration);
  112. BEGIN
  113. EnumParOut:= EnumParIn;
  114. IF (NOT Func3(EnumParIn) ) THEN
  115. EnumParOut:= Ident4;
  116. CASE EnumParIn OF
  117. Ident1: EnumParOut:= Ident1 ;
  118. Ident2: IF (IntGlob > 100) THEN EnumParOut:= Ident1
  119. ELSE EnumParOut:= Ident4;
  120. Ident3: EnumParOut:= Ident2 ;
  121. Ident4: ;
  122. Ident5: EnumParOut:= Ident3;
  123. END;
  124. END ;
  125. PROCEDURE Proc1( inIdx : integer );
  126. var
  127. i : integer;
  128. BEGIN
  129. i := MyRec[inIdx].PtrComp;
  130. MyRec[i] := MyRec[PtrGlb];
  131. MyRec[inIdx].IntComp := 5;
  132. MyRec[i].IntComp:= MyRec[inIdx].IntComp;
  133. MyRec[i].PtrComp:= i;
  134. Proc3( MyRec[i].PtrComp );
  135. IF ( MyRec[i].Discr = Ident1 ) THEN
  136. BEGIN
  137. MyRec[i].IntComp:= 6;
  138. Proc6( MyRec[inIdx].EnumComp, MyRec[i].EnumComp );
  139. MyRec[i].PtrComp:= MyRec[PtrGlb].PtrComp;
  140. Proc7( MyRec[i].IntComp, 10, MyRec[i].IntComp );
  141. END
  142. ELSE
  143. MyRec[inIdx] := MyRec[i];
  144. END;
  145. PROCEDURE Proc2(VAR IntParIO : OneToFifty);
  146. VAR
  147. IntLoc : OneToFifty;
  148. EnumLoc : Enumeration;
  149. BEGIN
  150. IntLoc:= IntParIO + 10;
  151. REPEAT
  152. IF (Char1Glob = 'A') THEN
  153. BEGIN
  154. IntLoc:= IntLoc - 1;
  155. IntParIO:= IntLoc - IntGlob;
  156. EnumLoc:= Ident1;
  157. END;
  158. UNTIL EnumLoc = Ident1;
  159. END ;
  160. PROCEDURE Proc4;
  161. VAR
  162. BoolLoc : BOOLEAN;
  163. BEGIN
  164. BoolLoc:= Char1Glob = 'A';
  165. BoolLoc:= BoolLoc OR BoolGlob;
  166. Char2Glob:= 'B';
  167. END ;
  168. PROCEDURE Proc5;
  169. BEGIN
  170. Char1Glob:= 'A';
  171. BoolGlob:= FALSE;
  172. END ;
  173. PROCEDURE Proc8(VAR Array1Par : Array1Dim; VAR Array2Par : Array2Dim;
  174. IntParI1, IntParI2 : OneToFifty);
  175. VAR
  176. IntLoc : OneToFifty;
  177. IntIndex : OneToFifty;
  178. BEGIN
  179. IntLoc:= IntParI1 + 5;
  180. Array1Par[IntLoc]:= IntParI2;
  181. Array1Par[IntLoc+1]:= Array1Par[IntLoc];
  182. Array1Par[IntLoc+30]:= IntLoc;
  183. FOR IntIndex:= IntLoc TO (IntLoc+1) DO
  184. Array2Par[IntLoc,IntIndex]:= IntLoc;
  185. { Array2Par[IntLoc,IntLoc-1]:= Array2Par[IntLoc,IntLoc-1] + 1; }
  186. Array2Par[IntLoc+20,IntLoc]:= Array1Par[IntLoc];
  187. IntGlob:= 5;
  188. END ;
  189. FUNCTION Func1(CharPar1, CharPar2 : CapitalLetter) : Enumeration;
  190. VAR
  191. CharLoc1, CharLoc2 : CapitalLetter;
  192. BEGIN
  193. CharLoc1:= CharPar1;
  194. CharLoc2:= CharLoc1;
  195. IF (CharLoc2 <> CharPar2) THEN
  196. Func1:= (Ident1)
  197. ELSE
  198. Func1:= (Ident2);
  199. END ;
  200. FUNCTION Func2(VAR StrParI1, StrParI2 : String30) : BOOLEAN;
  201. VAR
  202. IntLoc : OneToThirty;
  203. CharLoc : CapitalLetter;
  204. BEGIN
  205. IntLoc := 2;
  206. WHILE (IntLoc <= 2) DO
  207. BEGIN
  208. IF (Func1(StrParI1[IntLoc], StrParI2[IntLoc+1]) = Ident1) THEN
  209. BEGIN
  210. CharLoc := 'A';
  211. IntLoc:= IntLoc + 1;
  212. END;
  213. END;
  214. IF (CharLoc >= 'W') AND (CharLoc <= 'Z') THEN IntLoc:= 7;
  215. IF CharLoc = 'X' THEN
  216. Func2:= TRUE
  217. ELSE IF StrParI1 > StrParI2 THEN
  218. BEGIN
  219. IntLoc:= IntLoc + 7;
  220. Func2:= TRUE;
  221. END
  222. ELSE
  223. Func2:= FALSE;
  224. END ;
  225. PROCEDURE Proc0;
  226. VAR
  227. IntLoc1 : OneToFifty;
  228. IntLoc2 : OneToFifty;
  229. IntLoc3 : OneToFifty;
  230. CharLoc : CHAR;
  231. CharIndex : CHAR;
  232. EnumLoc : Enumeration;
  233. String1Loc,
  234. String2Loc : String30;
  235. i,
  236. j : INTEGER;
  237. BEGIN
  238. {
  239. NEW(PtrGlbNext);
  240. NEW(PtrGlb);
  241. }
  242. MyRec[PtrGlb].PtrComp:= PtrGlbNext;
  243. MyRec[PtrGlb].Discr:= Ident1;
  244. MyRec[PtrGlb].EnumComp:= Ident3;
  245. MyRec[PtrGlb].IntComp:= 40;
  246. MyRec[PtrGlb].StringComp := 'DHRYSTONE PROGRAM, SOME STRING';
  247. String1Loc := 'DHRYSTONE PROGRAM, 1''ST STRING';
  248. FOR i := 1 TO LOOPS DO
  249. FOR j := 1 TO 1000 DO
  250. BEGIN
  251. Proc5;
  252. Proc4;
  253. IntLoc1:= 2;
  254. IntLoc2:= 3;
  255. String2Loc := 'DHRYSTONE PROGRAM, 2''ND STRING';
  256. EnumLoc:= Ident2;
  257. BoolGlob:= NOT Func2(String1Loc, String2Loc);
  258. WHILE (IntLoc1 < IntLoc2) DO
  259. BEGIN
  260. IntLoc3 := 5 * IntLoc1 - IntLoc2;
  261. Proc7(IntLoc1, IntLoc2, IntLoc3);
  262. IntLoc1:= IntLoc1 + 1;
  263. END;
  264. Proc8(Array1Glob, Array2Glob, IntLoc1, IntLoc3);
  265. Proc1(PtrGlb);
  266. CharIndex:= 'A';
  267. WHILE CharIndex <= Char2Glob DO
  268. BEGIN
  269. IF (EnumLoc = Func1(CharIndex, 'C')) THEN
  270. Proc6(Ident1, EnumLoc);
  271. { CharIndex:= SUCC(CharIndex); }
  272. inc(byte(charindex));
  273. END;
  274. IntLoc3:= IntLoc2 * IntLoc1;
  275. IntLoc2:= IntLoc3 DIV IntLoc1;
  276. IntLoc2:= 7 * (IntLoc3 - IntLoc2) - IntLoc1;
  277. Proc2(IntLoc1);
  278. END;
  279. END;
  280. { The Main Program is trivial }
  281. BEGIN
  282. writeln( 'Start of Dhrystone benchmark' );
  283. start;
  284. Proc0;
  285. stop;
  286. END.