1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
| | ;; -*- lexical-binding: t; -*-
;; Copyright (C) 2019 Free Software Foundation, Inc.
;; This file is part of GNU Emacs.
;; GNU Emacs is free software: you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
;; the Free Software Foundation, either version 3 of the License, or
;; (at your option) any later version.
;; GNU Emacs is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
;; GNU General Public License for more details.
;; You should have received a copy of the GNU General Public License
;; along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>.
;;; Commentary:
;; Porting to elisp of the famous Dhrystone benchmark
;;
;; Adapted from C version:
;; https://github.com/Keith-S-Thompson/dhrystone/blob/master/v2.2/dry.c
(require 'cl-lib)
(cl-defstruct dhry-record
discr
variant)
(cl-defstruct dhry-var-1
enum-comp
int-comp
str-comp)
(cl-defstruct dhry-var-2
e-comp-2
str-2-comp)
(cl-defstruct dhry-var-3
ch-1-comp
ch-2-comp)
(defvar dhry-ptr-glob)
(defvar dhry-next-ptr-glob)
(defvar dhry-int-glob)
(defvar dhry-bool-glob)
(defvar dhry-ch-1-glob)
(defvar dhry-ch-2-glob)
(defvar dhry-arr-1-glob)
(defvar dhry-arr-2-glob)
(defun dhry-structassign (dst src)
(setf (cdr dst) (cdr src))
(let ((src-record (car src))
(dst-record (car dst)))
(setf (dhry-record-discr dst-record)
(dhry-record-discr src-record))
(let ((type (dhry-record-discr src-record))
(src-variant (dhry-record-variant src-record))
(dst-variant (dhry-record-variant dst-record)))
(cl-case type
(0
(setf (dhry-var-1-int-comp dst-variant)
(dhry-var-1-int-comp src-variant))
(setf (dhry-var-1-enum-comp dst-variant)
(dhry-var-1-enum-comp src-variant))
(store-substring (dhry-var-1-str-comp dst-variant)
0
(dhry-var-1-str-comp src-variant)))
(1
(setf (dhry-var-2-e-comp-2 dst-variant)
(dhry-var-2-e-comp-2 src-variant))
(store-substring (dhry-var-2-str-2-comp dst-variant)
0
(dhry-var-2-str-2-comp src-variant)))
(2
(setf (dhry-var-3-ch-1-comp dst-variant)
(dhry-var-3-ch-1-comp src-variant))
(setf (dhry-var-3-ch-2-comp dst-variant)
(dhry-var-3-ch-2-comp src-variant)))))))
(defun dhry-proc-1 (ptr-val-par)
(let ((next-record (cdr ptr-val-par)))
(dhry-structassign (cdr ptr-val-par) dhry-ptr-glob)
(setf (dhry-var-1-int-comp (dhry-record-variant (car ptr-val-par))) 5)
(setf (dhry-var-1-int-comp (dhry-record-variant (car next-record)))
(dhry-var-1-int-comp (dhry-record-variant (car ptr-val-par))))
(setf (cdr next-record) (dhry-proc-3 (cdr next-record)))
(if (= (dhry-record-discr (car next-record)) 0)
(progn
(setf (dhry-var-1-int-comp (dhry-record-variant (car next-record))) 6)
(setf (dhry-var-1-enum-comp (dhry-record-variant (car next-record)))
(dhry-proc-6 (dhry-var-1-enum-comp (dhry-record-variant (car ptr-val-par)))))
(setf (cdr next-record) (cdr dhry-ptr-glob))
(setf (dhry-var-1-int-comp (dhry-record-variant (car next-record)))
(dhry-proc-7 (dhry-var-1-int-comp (dhry-record-variant (car next-record))) 10)))
(dhry-structassign ptr-val-par (cdr ptr-val-par)))))
(defun dhry-proc-2 (int-par-ref)
(let (int-loc enum-loc)
(setq int-loc (+ int-par-ref 10))
(cl-loop when (= dhry-ch-1-glob ?A)
do (cl-decf int-loc)
(setq int-par-ref (- int-loc dhry-int-glob))
(setq enum-loc 0)
while (/= enum-loc 0))
int-par-ref))
(defun dhry-proc-3 (ptr-ref-par)
(let ((ret ptr-ref-par))
(when dhry-ptr-glob
(setq ret (cdr dhry-ptr-glob)))
(setf (dhry-var-1-int-comp (dhry-record-variant (car dhry-ptr-glob))) (dhry-proc-7 10 dhry-int-glob))
ret))
(defun dhry-proc-4 ()
(let (bool-loc)
(setq bool-loc (= dhry-ch-1-glob ?A))
(setq dhry-bool-glob (or bool-loc dhry-bool-glob))
(setq dhry-ch-2-glob ?B)))
(defun dhry-proc-5 ()
(setq dhry-ch-1-glob ?A)
(setq dhry-bool-glob nil))
(defun dhry-proc-6 (enum-val-par)
(let (enum-ref-par)
(setq enum-ref-par enum-val-par)
(unless (dhry-func-3 enum-val-par)
(setq enum-ref-par 3))
(cl-case enum-val-par
(0
(setq enum-ref-par 0))
(1
(if (> dhry-int-glob 100)
(setq enum-ref-par 0)
(setq enum-ref-par 3)))
(2
(setq enum-ref-par 1))
(3
nil)
(4
(setq enum-ref-par 2)))
enum-ref-par))
(defun dhry-proc-7 (int-1-par-val int-2-par-val)
(let (int-loc)
(setq int-loc (+ int-1-par-val 2))
(+ int-2-par-val int-loc)))
(defun dhry-proc-8 (arr-1-par-ref arr-2-par-ref int-1-par-val int-2-par-val)
(let (int-loc)
(setq int-loc (+ int-1-par-val 5))
(setf (aref arr-1-par-ref int-loc) int-2-par-val)
(setf (aref arr-1-par-ref (1+ int-loc)) (aref arr-1-par-ref int-loc))
(setf (aref arr-1-par-ref (+ int-loc 30)) int-loc)
(cl-loop for int-index from int-loc to (1+ int-loc)
do (setf (aref (aref arr-2-par-ref int-loc) int-index) int-loc))
(cl-incf (aref (aref arr-2-par-ref int-loc) (1- int-loc)))
(setf (aref (aref arr-2-par-ref (+ int-loc 20)) int-loc) (aref arr-1-par-ref int-loc))
(setq dhry-int-glob 5)))
(defun dhry-func-1 (ch-1-par-val ch-2-par-val)
(let (ch-1-loc ch-2-loc)
(setq ch-1-loc ch-1-par-val)
(setq ch-2-loc ch-1-loc)
(if (/= ch-2-loc ch-2-par-val)
0
(setq dhry-ch-1-glob ch-1-loc)
1)))
(defun dhry-func-2 (str-1-par-ref str-2-par-ref)
(let (int-loc ch-loc)
(setq int-loc 2)
(while (<= int-loc 2)
(if (= (dhry-func-1 (aref str-1-par-ref int-loc)
(aref str-2-par-ref (1+ int-loc)))
0)
(progn
(setq ch-loc ?A)
(cl-incf int-loc))))
(if (and (>= ch-loc ?W) (< ch-loc ?Z))
(setq int-loc 7))
(if (= ch-loc ?R)
t
(if (string> str-1-par-ref str-2-par-ref)
(progn
(cl-incf int-loc 7)
(setq dhry-int-glob int-loc)
t)
nil))))
(defun dhry-func-3 (enum-par-val)
(let (enum-loc)
(setq enum-loc enum-par-val)
(if (= enum-loc 2)
t
nil)))
(defun dhrystone (number-of-runs &optional check)
(let (int-1-loc
int-2-loc
int-3-loc
enum-loc
(str-1-loc (make-string 30 0))
(str-2-loc (make-string 30 0)))
;; initialization (pre-allocate to avoid consing in the loop)
(setq dhry-ptr-glob (list (make-dhry-record) (make-dhry-record)))
(setf (dhry-record-discr (car dhry-ptr-glob)) 0)
(setf (dhry-record-variant (car dhry-ptr-glob))
(make-dhry-var-1
:enum-comp 2
:int-comp 40
:str-comp "DHRYSTONE PROGRAM, SOME STRING"))
(setf (dhry-record-variant (cadr dhry-ptr-glob))
(make-dhry-var-1
:str-comp (make-string 30 0)))
(setq dhry-int-glob 0)
(setq dhry-bool-glob nil)
(setq dhry-ch-1-glob 0)
(setq dhry-ch-2-glob 0)
(setq dhry-arr-1-glob (make-vector 50 0))
(setq dhry-arr-2-glob (make-vector 50 0))
(dotimes (i 50)
(setf (aref dhry-arr-2-glob i) (make-vector 50 0)))
(setf (aref (aref dhry-arr-2-glob 8) 7) 10)
(store-substring str-1-loc 0 "DHRYSTONE PROGRAM, 1'ST STRING")
;; dhrystone loop
(dotimes (run-index number-of-runs)
(dhry-proc-5)
(dhry-proc-4)
(setq int-1-loc 2)
(setq int-2-loc 3)
(store-substring str-2-loc 0 "DHRYSTONE PROGRAM, 2'ND STRING")
(setq enum-loc 1)
(setq dhry-bool-glob (not (dhry-func-2 str-1-loc str-2-loc)))
(while (< int-1-loc int-2-loc)
(setq int-3-loc (- (* 5 int-1-loc) int-2-loc))
(setq int-3-loc (dhry-proc-7 int-1-loc int-2-loc))
(cl-incf int-1-loc))
(dhry-proc-8 dhry-arr-1-glob dhry-arr-2-glob int-1-loc int-3-loc)
(dhry-proc-1 dhry-ptr-glob)
(cl-loop for ch-index from ?A to dhry-ch-2-glob
when (= enum-loc (dhry-func-1 ch-index ?C))
do (setq enum-loc (dhry-proc-6 0))
(store-substring str-2-loc 0 "DHRYSTONE PROGRAM, 3'RD STRING")
(setq int-2-loc run-index)
(setq dhry-int-glob run-index))
(setq int-2-loc (* int-2-loc int-1-loc))
(setq int-1-loc (/ int-2-loc int-3-loc))
(setq int-2-loc (- (* 7 (- int-2-loc int-3-loc)) int-1-loc))
(setq int-1-loc (dhry-proc-2 int-1-loc)))
;; check results
(when check
(cl-flet ((result-compare (name val ref)
(unless (equal val ref)
(error "%s: %s, expected: %s" name val ref))))
(result-compare "Int_Glob"
dhry-int-glob 5)
(result-compare "Bool_Glob"
dhry-bool-glob t)
(result-compare "Ch_1_Glob"
dhry-ch-1-glob ?A)
(result-compare "Ch_2_Glob"
dhry-ch-2-glob ?B)
(result-compare "Arr_1_Glob[8]"
(aref dhry-arr-1-glob 8) 7)
(result-compare "Arr_2_Glob[8][7]"
(aref (aref dhry-arr-2-glob 8) 7) (+ number-of-runs 10))
(result-compare "Ptr_Glob->Discr"
(dhry-record-discr (car dhry-ptr-glob)) 0)
(result-compare "Ptr_Glob->var_1->Enum_Comp"
(dhry-var-1-enum-comp (dhry-record-variant (car dhry-ptr-glob))) 2)
(result-compare "Ptr-Glob->var_1->Int_Comp"
(dhry-var-1-int-comp (dhry-record-variant (car dhry-ptr-glob))) 17)
(result-compare "Ptr_Glob->var_1->Str_Comp"
(dhry-var-1-str-comp (dhry-record-variant (car dhry-ptr-glob))) "DHRYSTONE PROGRAM, SOME STRING")
(result-compare "Next_Ptr_Glob->Discr"
(dhry-record-discr (cadr dhry-ptr-glob)) 0)
(result-compare "Next_Ptr_Glob->var_1->Enum_Comp"
(dhry-var-1-enum-comp (dhry-record-variant (cadr dhry-ptr-glob))) 1)
(result-compare "Next_Ptr_Glob->var_1->Int_Comp"
(dhry-var-1-int-comp (dhry-record-variant (cadr dhry-ptr-glob))) 18)
(result-compare "Next_Ptr_Glob->var_1->Str_Comp"
(dhry-var-1-str-comp (dhry-record-variant (cadr dhry-ptr-glob))) "DHRYSTONE PROGRAM, SOME STRING")
(result-compare "Int_1_Loc"
int-1-loc 5)
(result-compare "Int_2_Loc"
int-2-loc 13)
(result-compare "Int_3_Loc"
int-3-loc 7)
(result-compare "Enum_Loc"
enum-loc 1)
(result-compare "Str_1_Loc"
str-1-loc "DHRYSTONE PROGRAM, 1'ST STRING")
(result-compare "Str_2_Loc"
str-2-loc "DHRYSTONE PROGRAM, 2'ND STRING")))))
(defun elb-dhrystone-entry ()
(dhrystone 1000000))
(provide 'elb-dhrystone)
|