OpenCores
URL https://opencores.org/ocsvn/zipcpu/zipcpu/trunk

Subversion Repositories zipcpu

[/] [zipcpu/] [trunk/] [bench/] [asm/] [zipdhry.S] - Blame information for rev 209

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 50 dgisselq
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2
;
3
; Filename:     zipdhry.S
4
;
5
; Project:      Zip CPU -- a small, lightweight, RISC CPU soft core
6
;
7
; Purpose:      Zip assembly file for running the Dhrystone benchmark in the
8
;               Zip CPU.
9
;
10 209 dgisselq
;       ****************************
11
;
12
;       This file is long since out of date.  It is kept around for historical
13
;       reasons only.  In many ways, this file never truly accomplished the
14
;       Dhrystone test, since it is an assembly file (not compiled), and since
15
;       it uses internally and locally optimized library versions.
16
;
17
;       Another version of Dhrystone exists for the ZipCPU, in C, which properly
18
;       executes the benchmark.
19
;
20
;       ****************************
21
;
22
;
23 69 dgisselq
;       To calculate a DMIPS value, take the value of R0 upon completion.  This
24
;       is the number of clock ticks used from start to finish (i.e., from
25
;       entrance into user mode to the return to supervisor mode).  Let
26
;       CLKSPD be your clock speed in Hz.  Then:
27
;
28
;       DMIPS = (CLKSPD*NRUNS/R0) / 1757;
29
;
30
;       For my tests, CLKSPD = 100e6 Hz (100 MHz), NRUNS = 512.  Thus,
31
;
32
;       DMIPS = (100e6 * 512) / R0 / 1757
33
;
34
;
35 50 dgisselq
; Creator:      Dan Gisselquist, Ph.D.
36 69 dgisselq
;               Gisselquist Technology, LLC
37 50 dgisselq
;
38
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
39
;
40
; Copyright (C) 2015, Gisselquist Technology, LLC
41
;
42
; This program is free software (firmware): you can redistribute it and/or
43
; modify it under the terms of  the GNU General Public License as published
44
; by the Free Software Foundation, either version 3 of the License, or (at
45
; your option) any later version.
46
;
47
; This program is distributed in the hope that it will be useful, but WITHOUT
48
; ANY WARRANTY; without even the implied warranty of MERCHANTIBILITY or
49
; FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
50
; for more details.
51
;
52
; License:      GPL, v3, as defined and found on www.gnu.org,
53
;               http://www.gnu.org/licenses/gpl.html
54
;
55
;
56
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
57
;
58 41 dgisselq
// Under Verilator:
59 69 dgisselq
//      DMIPS:          30.3    100 MHz (sim)   0.29    // Initial baseline
60
//      DMIPS:          37.5    100 MHz (sim)   0.38    // 20151017
61
//      DMIPS:          38.0    100 MHz (sim)   0.38    // 20151211 (new ISA)
62
//      DMIPS:          40.5    100 MHz (sim)   0.41    // 20151212 (H/W DIV)
63
//      DMIPS:           8.2    100 MHz (sim)   0.08    // 20151104--!pipelined
64
//      DMIPS:          60.1    100 MHz (sim)   0.60    // 20151215 (New PF)
65 74 dgisselq
//      DMIPS:          60.0    100 MHz (sim)   0.60    // 20151226 (BugFix)
66 152 dgisselq
//      DMIPS:                  100 MHz (sim)   0.67    // 20160406 (??)
67
//      DMIPS:                  100 MHz (sim)   0.58    // 20160409 (BugFix)
68 69 dgisselq
// On real hardware:
69
//      DMIPS:          24.7    100 MHz (basys) 0.25    // Initial baseline
70
//      DMIPS:          30.6    100 MHz (basys) 0.31    // 20151017
71 74 dgisselq
//      DMIPS:          48.4    100 MHz (basys) 0.48    // 20151227 (New pf/ISA)
72 57 dgisselq
//
73 69 dgisselq
// (And, under Verilator, if the cache holds the entire 4kW program: 55.1 DMIPS)
74 57 dgisselq
//
75 69 dgisselq
//
76 57 dgisselq
//   with no loop unrolling nor function inlining
77
//      DMIPS:          24.3    100 MHz (sim)   0.24
78
//   with packed strings
79
//      DMIPS:          35.6    100 MHz (sim)   0.36
80
//
81 41 dgisselq
// For comparison:
82 69 dgisselq
//      uBlaze:         230     177 MHz         1.3
83 41 dgisselq
//      LEON3                                   1.4
84
//      NiOS II:        218     185 MHz         1.16
85
//      OpenRisk        250     250 MHz         1.00
86
//      LM32                                    1.14
87
//      ZPU             2.6      50 MHz         0.05
88
//
89
 
90 57 dgisselq
// Some #def's to control compilation.
91
//
92
// SKIP_SHORT_CIRCUITS determines whether or not we do internal testing and
93
// jump to a BUSY instruction on failure for the debugger to pick up.  Skip
94 69 dgisselq
// this for valid testing.  Enable it and see whether or not zipdhry dies mid
95
// process--if it down, you got there--so fix it.
96 57 dgisselq
//
97 69 dgisselq
#define SKIP_SHORT_CIRCUITS
98 57 dgisselq
//
99 69 dgisselq
//
100
//
101 57 dgisselq
// NO_INLINE controls whether or not we inline certain functions.  If you
102
// define this, nothing will be inlined.
103 69 dgisselq
//
104
// I recommend not setting this define.
105
//
106 57 dgisselq
// #define      NO_INLINE
107
//
108 69 dgisselq
//
109
//
110 57 dgisselq
// NO_LOOP_UNROLLING controls loop unrolling.  The default is to unroll loops
111 69 dgisselq
// by a factor of 4x.  By defining this, all loop unrolling is removed.  (Well,
112
// except the pipelined strcpy and strcmp below--those loops are automatically
113
// unrolled as part of being piped.  Undefine those as well and all loops will
114
// be effectively unrolled.
115
//
116
// I recommend not setting this define.
117
//
118 41 dgisselq
// #define      NO_LOOP_UNROLLING
119 57 dgisselq
//
120
//
121 69 dgisselq
//
122
// After building this whole thing and putting it together, I discovered another
123
// means I could use of generating a return statement.  In this case, instead
124
// of LOD -1(SP),PC, I would load the return PC from the stack as part of the
125
// pipelined memory operations, adjust the stack pointer, and jump to the
126
// register address.  It saves clocks because it uses the pipelined memory
127
// operation, but other than that it suffers the same number of stalls.
128
//
129
// Fast returns used to be controlled by a #define.  This has been removed,
130
// and all returns are "fast" by default.
131
//
132
//
133
//
134
//
135
//
136
// SKIP_DIVIDE controlls whether or not we want to calculate the speed of
137
// our processor assuming we had a divide instruction.  If you skip the
138
// divide, it will be as though you had such an instruction.  Otherwise,
139
// leave it in and the test bench will measure how long it takes to run
140
// while including the divide emulation.
141
//
142
// I recommend leaving this undefined, for a more accurate measure.
143
//
144
// #define      SKIP_DIVIDE     // 0xace17/0x50f37 vs 0xbd817/0x57d37
145
//
146
// Thus a divide instruction might raise our score from 37.5 to 41.1, or
147
// from 81 to 87.8--depending on whether or not the cache is loaded or not.
148
//
149
//
150
//
151
//
152
// HARDWARE_DIVIDE is appropriate when the hardware has a divide instruction,
153
// as it will use this divide instruction for the one time a divide is needed.
154
//
155
// I recommended setting this value ... IF the hardware has the divide
156
// instruction built in.
157
//
158
#define HARDWARE_DIVIDE
159
//
160
//
161
// PIPELINED_STRCPY and PIPELINED_STRCMP both have to do with whether or not
162
// the memory accesses of each of these "library" functions are pipelined.
163
// As you may recall, the Zip CPU allows you to pipeline memory accesses
164
// that are all done with the same condition, and that all reference either
165
// the same or increasing addresses.  These one-clock memory access instructions
166
// are ridiculously fast (when available), and we would be foolish not to use
167
// them.  These two defines modify the library functions to use this mode
168
// and to capitalize upon it as much as possible.
169
//
170
// I recommend setting these.
171
//
172
#define PIPELINED_STRCPY
173
#define PIPELINED_STRCMP
174
//
175
//
176 74 dgisselq
        dev.scope.cpu   equ     0x0120
177 41 dgisselq
        sys.ctr.mtask   equ     0xc0000008
178
// int main(int argc, char **argv) {
179
//      dhrystone();
180
// }
181 74 dgisselq
// #define      LOAD_ADDRESS    entry+PC
182
#define LOAD_ADDRESS    lcl_strcpy+PC
183 41 dgisselq
entry:
184 86 dgisselq
        ; LDI   0x0c000010,R0
185
        ; LDI   dev.scope.cpu,R1
186
        ; STO   R0,(R1)
187 74 dgisselq
        ;
188 41 dgisselq
        MOV     top_of_stack(PC),uSP
189
        MOV     entry(PC),uR12
190
        ; Store  our tick counter in R1
191
        LDI     sys.ctr.mtask,R1
192
        ; And start with our counter cleared at zero
193
        CLR     R0
194
        STO     R0,(R1)
195
#ifdef  SUPERVISOR_TASK
196 69 dgisselq
        MOV     __HERE__+2(PC),R0
197 41 dgisselq
        BRA     dhrystone
198
#else
199
        MOV     dhrystone(PC),uPC
200
        RTU
201
#endif
202
        ; Read the tick counter back out
203
        LOD     (R1),R0
204
        HALT    ; Stop the CPU--We're done!!!!!!!
205
 
206 74 dgisselq
//
207 41 dgisselq
// typedef      enum { Ident_1, Ident_2, Ident_3, Ident_4, Ident_5 } test_enum;
208
// typedef      enum { false, true } bool;
209
 
210
// typedef      int     Arr_1_Dim[50];
211
// typedef      int     Arr_2_Dim[50][50];
212
#define RECSIZE 35
213
#define NUMBER_OF_RUNS  (512)
214
        ptr_comp                        equ     0
215
        discr                           equ     1
216
        variant.var_1.enum_comp         equ     2
217
        variant.var_1.int_comp          equ     3
218
        variant.var_1.str_comp          equ     4
219
 
220 69 dgisselq
 
221 41 dgisselq
//char  *lcl_strcpy(char *d, char *s) {
222
//      char    *cpd = d, ch;
223
//
224
//      do{
225
//              *cpd++ = ch = *s++;
226
//      } while(ch);
227
//
228
//}
229
//
230 69 dgisselq
 
231
#ifdef  PIPELINED_STRCPY
232
; On entry,
233
;       R0 = dst
234
;       R1 = src
235
;       R2 = return address
236 41 dgisselq
lcl_strcpy:
237 69 dgisselq
        SUB     4,SP
238
        STO     R2,(SP)
239
        STO     R3,1(SP)
240
        STO     R4,2(SP)
241
        STO     R5,3(SP)
242
 
243
copy_next_char:
244 41 dgisselq
        ; R0 = d
245
        ; R1 = s
246
        ; R3 = ch
247 69 dgisselq
        LOD     (R1),R2
248
        LOD     1(R1),R3
249
        LOD     2(R1),R4
250
        LOD     3(R1),R5
251
 
252
        CMP     0,R2
253
        CMP.NZ  0,R3
254
        CMP.NZ  0,R4
255
        CMP.NZ  0,R5
256
        BZ      end_strcpy
257
 
258
        STO     R2,(R0)
259
        STO     R3,1(R0)
260
        STO     R4,2(R0)
261
        STO     R5,3(R0)
262
 
263
        ADD     4,R1
264
        ADD     4,R0
265
        BRA copy_next_char
266
 
267
end_strcpy:
268 202 dgisselq
        STO     R2,(R0)
269 69 dgisselq
        CMP     0,R2
270 202 dgisselq
        STO.NZ  R3,1(R0)
271 69 dgisselq
        CMP.NZ  0,R3
272 202 dgisselq
        STO.NZ  R4,2(R0)
273 69 dgisselq
        CMP.NZ  0,R4
274 74 dgisselq
        STO.NZ  R5,3(R0)
275 69 dgisselq
 
276
        LOD     (SP),R2
277
        LOD     1(SP),R3
278
        LOD     2(SP),R4
279
        LOD     3(SP),R5
280
        ADD     4,SP
281 74 dgisselq
#ifndef SKIP_SHORT_CIRCUITS
282
        CMP     LOAD_ADDRESS,R2
283
        HALT.LT
284
#endif
285 69 dgisselq
        JMP     R2
286
 
287
#else
288
lcl_strcpy:
289
        ; R0 = d
290
        ; R1 = s
291
        ; R3 = ch
292 57 dgisselq
copy_next_char:
293 69 dgisselq
        SUB     1,SP
294
        STO     R2,(SP)
295 41 dgisselq
#ifdef  NO_LOOP_UNROLLING
296
        LOD     (R1),R2
297
        STO     R2,(R0)
298 57 dgisselq
        CMP     0,R2
299 69 dgisselq
        BZ      lcl_strcpy_end_of_loop
300 41 dgisselq
        ADD     1,R0
301
        ADD     1,R1
302 57 dgisselq
        BRA     copy_next_char
303
 
304 41 dgisselq
#else
305
        LOD     (R1),R2
306 57 dgisselq
        STO     R2,(R0)
307 41 dgisselq
        CMP     0,R2
308 69 dgisselq
        BZ      lcl_strcpy_end_of_loop
309 41 dgisselq
        LOD     1(R1),R2
310 57 dgisselq
        STO     R2,1(R0)
311 41 dgisselq
        CMP     0,R2
312 69 dgisselq
        BZ      lcl_strcpy_end_of_loop
313 41 dgisselq
        LOD     2(R1),R2
314 57 dgisselq
        STO     R2,2(R0)
315 41 dgisselq
        CMP     0,R2
316 69 dgisselq
        BZ      lcl_strcpy_end_of_loop
317 41 dgisselq
        LOD     3(R1),R2
318 57 dgisselq
        STO     R2,3(R0)
319 41 dgisselq
        CMP     0,R2
320 69 dgisselq
        BZ      lcl_strcpy_end_of_loop
321 41 dgisselq
        ADD     4,R0
322
        ADD     4,R1
323 57 dgisselq
        BRA     copy_next_char
324 41 dgisselq
#endif
325 69 dgisselq
lcl_strcpy_end_of_loop:
326
        LOD     (SP),R2
327
        ADD     1,SP
328 74 dgisselq
#ifndef SKIP_SHORT_CIRCUITS
329
        CMP     LOAD_ADDRESS,R2
330
        BUSY.LT
331
#endif
332 69 dgisselq
        JMP     R2
333
#endif
334 41 dgisselq
 
335
//int   lcl_strcmp(char *s1, char *s2) {
336
//      char    a, b;
337
//      do {
338
//              a = *s1++; b = *s2++;
339
//      } while((a)&&(a==b));
340
//
341
//      return a-b;
342
//}
343
 
344 69 dgisselq
#ifdef  PIPELINED_STRCMP
345 41 dgisselq
lcl_strcmp:
346 69 dgisselq
        SUB     8,SP
347
        STO     R2,(SP)
348 41 dgisselq
        STO     R3,1(SP)
349 69 dgisselq
        STO     R4,2(SP)
350
        STO     R5,3(SP)
351
        STO     R6,4(SP)
352
        STO     R7,5(SP)
353
        STO     R8,6(SP)
354
        STO     R9,7(SP)
355 41 dgisselq
 
356
strcmp_top_of_loop:
357 69 dgisselq
        LOD     (R0),R2
358
        LOD     1(R0),R3
359
        LOD     2(R0),R4
360
        LOD     3(R0),R5
361
        ;
362
        LOD     (R1),R6
363
        LOD     1(R1),R7
364
        LOD     2(R1),R8
365
        LOD     3(R1),R9
366
        ;
367 74 dgisselq
        ;
368 69 dgisselq
        CMP     0,R2
369
        CMP.NZ  0,R3
370
        CMP.NZ  0,R4
371
        CMP.NZ  0,R5
372
        BZ      strcmp_end_loop
373
 
374
        CMP     R2,R6
375
        CMP.Z   R3,R7
376
        CMP.Z   R4,R8
377
        CMP.Z   R5,R9
378
        BNZ     strcmp_end_loop
379
 
380
        ADD     4,R0
381
        ADD     4,R1
382
        BRA     strcmp_top_of_loop
383
 
384
strcmp_end_loop:
385
        CMP     0,R2
386
        BZ      final_str_compare
387
        CMP     R2,R6
388
        BNZ     final_str_compare
389
 
390
        MOV     R3,R2
391
        MOV     R7,R6
392
        CMP     0,R2
393
        BZ      final_str_compare
394
        CMP     R2,R6
395
        BNZ     final_str_compare
396
 
397
        MOV     R4,R2
398
        MOV     R8,R6
399
        CMP     0,R2
400
        BZ      final_str_compare
401
        CMP     R2,R6
402
        BNZ     final_str_compare
403
 
404
        MOV     R5,R2
405
        MOV     R9,R6
406
 
407
final_str_compare:
408
        SUB     R6,R2
409
        MOV     R2,R0
410
 
411
        LOD     (SP),R2
412
        LOD     1(SP),R3
413
        LOD     2(SP),R4
414
        LOD     3(SP),R5
415
        LOD     4(SP),R6
416
        LOD     5(SP),R7
417
        LOD     6(SP),R8
418
        LOD     7(SP),R9
419
        ADD     8,SP
420 74 dgisselq
#ifndef SKIP_SHORT_CIRCUITS
421
        CMP     LOAD_ADDRESS,R2
422
        BUSY.LT
423
#endif
424 69 dgisselq
        JMP     R2
425
 
426
#else
427
lcl_strcmp:
428
        SUB     2,SP
429
        STO     R2,(SP)
430
        STO     R3,1(SP)
431
 
432
strcmp_top_of_loop:
433 41 dgisselq
#ifdef  NO_LOOP_UNROLLING
434 57 dgisselq
        ; LOD   (R0),R2
435
        ; LOD   (R1),R3                 ; Alternate approach:
436 41 dgisselq
        ; CMP   R2,R3                   ;       CMP     0,R2
437
        ; BNZ   strcmp_end_loop         ;       BZ      strcmp_end_loop
438
        ; CMP   0,R2                    ;       CMP     R2,R3
439
        ; BZ    strcmp_end_loop         ;       BZ      strcmp_top_of_loop
440
        ; CMP   0,R3                    ;
441
        ; BZ    strcmp_end_loop         ;
442
        ; ADD   1,R0
443
        ; ADD   1,R1
444
        ; BRA   strcmp_top_of_loop
445
        LOD     (R0),R2
446
        LOD     (R1),R3
447
        CMP     0,R2
448
        BZ      strcmp_end_loop
449 57 dgisselq
        ADD     1,R0
450
        ADD     1,R1
451 41 dgisselq
        CMP     R2,R3
452
        BZ      strcmp_top_of_loop
453
#else
454
        LOD     (R0),R2
455
        LOD     (R1),R3
456
        CMP     0,R2
457
        BZ      strcmp_end_loop
458
        CMP     R2,R3
459
        BNZ     strcmp_end_loop
460
        LOD     1(R0),R2
461
        LOD     1(R1),R3
462
        CMP     0,R2
463
        BZ      strcmp_end_loop
464
        CMP     R2,R3
465
        BNZ     strcmp_end_loop
466
        LOD     2(R0),R2
467
        LOD     2(R1),R3
468
        CMP     0,R2
469
        BZ      strcmp_end_loop
470
        CMP     R2,R3
471
        BNZ     strcmp_end_loop
472
        LOD     3(R0),R2
473
        LOD     3(R1),R3
474
        CMP     0,R2
475
        BZ      strcmp_end_loop
476
        CMP     R2,R3
477
        BNZ     strcmp_end_loop
478
        ADD     4,R0
479
        ADD     4,R1
480
        BRA     strcmp_top_of_loop
481
#endif
482
 
483
strcmp_end_loop:
484
        SUB     R3,R2
485
        MOV     R2,R0
486
 
487 69 dgisselq
        LOD     (SP),R2
488 41 dgisselq
        LOD     1(SP),R3
489 69 dgisselq
        ADD     2,SP
490 74 dgisselq
#ifndef SKIP_SHORT_CIRCUITS
491
        CMP     LOAD_ADDRESS,R2
492
        BUSY.LT
493
#endif
494 69 dgisselq
        JMP     R2
495
#endif
496 41 dgisselq
 
497
 
498
//test_enum     func_1(char ch_1, char ch_2) {
499
//      char    lcl_ch_1, lcl_ch_2;
500
//
501
//      lcl_ch_1 = ch_1;
502
//      lcl_ch_2 = lcl_ch_1;
503
//      if (lcl_ch_2 != ch_2)
504
//              return 0;
505
//      else {
506
//              gbl_ch = lcl_ch_1;
507
//              return 1;
508
//      }
509
 
510
#ifdef  NO_INLINE
511
func_1:
512
        ; On input,
513
        ; R0 = ch_1
514
        ; R1 = ch_2
515
        ; R2 = available
516
        ; On output, R0 is our return value
517
 
518 69 dgisselq
        SUB     1,SP
519
        STO     R2,(SP)
520 41 dgisselq
        MOV     R0,R2
521
        CMP     R2,R1
522
        CLR.NZ  R0
523
        STO.Z   R2,gbl_ch(R12)
524
        LDILO.Z 1,R0
525 69 dgisselq
        LOD     (SP),R2
526
        ADD     1,SP
527 74 dgisselq
#ifndef SKIP_SHORT_CIRCUITS
528
        CMP     LOAD_ADDRESS,R2
529
        BUSY.LT
530
#endif
531 69 dgisselq
        JMP     R2
532 41 dgisselq
#endif
533
 
534
//bool  func_2(char *str_1, char *str_2) {
535
//      int     lcl_int;
536
//      char    lcl_ch;
537
//
538
//      lcl_int = 2;
539
//      while(lcl_int <= 2) {
540
//              if (func_1(str_1[lcl_int], str_2[lcl_int+1])==0) {
541
//                      lcl_ch = 'A';
542
//                      lcl_int ++;
543
//              }
544
//      }
545
//
546
//      if ((lcl_ch >= 'W')&&(lcl_ch < 'Z'))
547
//              lcl_int = 7;
548
//      if (lcl_ch == 'R')
549
//              return true;
550
//      else {
551
//              if (lcl_strcmp(str_1, str_2)>0) {
552
//                      lcl_int += 7;
553
//                      gbl_int = lcl_int;
554
//              } else
555
//                      return false;
556
//      }
557
//}
558
func_2:
559
        ;
560
        SUB     6,SP
561 74 dgisselq
#ifndef SKIP_SHORT_CIRCUITS
562
        CMP     LOAD_ADDRESS,R2
563
        BUSY.LT
564
#endif
565
        STO     R2,(SP)         ; SP = 0x08daf
566 69 dgisselq
        STO     R3,1(SP)
567
        STO     R4,2(SP)
568
        STO     R5,3(SP)
569
        STO     R6,4(SP)
570
        STO     R7,5(SP)
571 41 dgisselq
 
572
        MOV     R0,R3   ; R3 = str_1
573
        MOV     R1,R4   ; R4 = str_2
574
        LDI     2,R5    ; R5 = lcl_int
575
        LDI     'A',R7  ; R7 = lcl_ch
576
func_2_while_loop:
577
        CMP     2,R5
578
        BGT     func_2_end_while_loop
579
func_2_top_while_loop:
580
        MOV     R3,R6
581
        ADD     R5,R6
582
 
583
#ifdef  NO_INLINE
584
        LOD     (R6),R0
585
        MOV     R4,R6
586
        ADD     R5,R6
587
        LOD     1(R6),R1
588
 
589 69 dgisselq
        MOV     __HERE__+2(PC),R2
590 41 dgisselq
        BRA     func_1
591
 
592
        CMP     0,R0
593
        ADD.Z   1,R5
594 57 dgisselq
#ifndef SKIP_SHORT_CIRCUITS
595
        BUSY.NZ
596
#endif
597 41 dgisselq
#else
598
        LOD     (R6),R2
599
        MOV     R4,R6
600
        ADD     R5,R6
601
        LOD     1(R6),R1
602
 
603
        CMP     R2,R1
604
        STO.Z   R2,gbl_ch(R12)
605
        LDILO.Z 1,R0
606
 
607
        ADD.NZ  1,R5
608 57 dgisselq
#ifndef SKIP_SHORT_CIRCUITS
609
        BUSY.Z
610 41 dgisselq
#endif
611 57 dgisselq
#endif
612 41 dgisselq
 
613
        CMP     3,R5
614
#ifndef SKIP_SHORT_CIRCUITS
615
        BUSY.LT
616
#endif
617
        BLT     func_2_top_while_loop
618
 
619
func_2_end_while_loop:
620
 
621
        // CMP  'W',R7                  // BUT! We know lcl_ch='A'
622
        // BLT  skip_if                 // So we can skip this
623
        // CMP  'Z',R7                  // entire  section
624
        // LDI.LT       7,R5
625
        // CMP  'R',R7
626
        // BNZ alt_if_case
627
        // LLO.Z        1,R0
628
        // BRA  func_2_return_and_cleanup
629
        //
630
        MOV     R3,R0
631
        MOV     R4,R1
632 69 dgisselq
        MOV     __HERE__+2(PC),R2
633 41 dgisselq
        BRA     lcl_strcmp
634
        CMP     0,R0
635
        BGT     func_2_final_then
636
        CLR     R0
637
        BRA     func_2_return_and_cleanup
638
func_2_final_then:
639
        // ADD  7,R5            ; Never read, so useless code
640
        LDI     1,R0
641
#ifndef SKIP_SHORT_CIRCUITS
642
        BUSY
643
#endif
644
func_2_return_and_cleanup:
645
 
646 69 dgisselq
        LOD     (SP),R2
647
        LOD     1(SP),R3
648
        LOD     2(SP),R4
649
        LOD     3(SP),R5
650
        LOD     4(SP),R6
651
        LOD     5(SP),R7
652 41 dgisselq
        ADD     6,SP
653 74 dgisselq
#ifndef SKIP_SHORT_CIRCUITS
654
        CMP     LOAD_ADDRESS,R2
655
        BUSY.LT
656
#endif
657 69 dgisselq
        JMP     R2
658 41 dgisselq
 
659
//bool  func_3(test_enum a) {
660
//      test_enum       lcl_enum;
661
//
662
//      lcl_enum = a;
663
//      if (lcl_enum == Ident_3)
664
//              return true;
665
//      else
666
//              return false;
667
//}
668
 
669
#ifdef  NO_INLINE
670
func_3:
671
        ; On entry,
672
        ;  R0 = a
673
        ;  R1 - available
674
        CMP     2,R0
675 69 dgisselq
        CLR     R0      ; CLR Doesn't set flags
676
        LDILO.Z 1,R0
677 74 dgisselq
#ifndef SKIP_SHORT_CIRCUITS
678
        CMP     LOAD_ADDRESS,R1
679
        BUSY.LT
680
#endif
681 69 dgisselq
        JMP     R1
682 41 dgisselq
#endif
683
 
684
 
685
// void proc_6(test_enum ev, test_enum *ep) {
686
//      *ep = ev;
687
//      if (!func_3(ev))
688
//              *ep = 3;
689
//      switch(ev) {
690
//              case 0: *ep = 0; break;
691
//              case 1:
692
//                      if (gbl_int > 100)
693
//                              *ep = 0;
694
//                      else
695
//                              *ep = 3;
696
//                      break;
697
//              case 2:
698
//                      *ep = 1;
699
//                      break;
700
//              case 3:
701
//                      break;
702
//              case 4:
703
//                      *ep = 2;
704
//      }
705
//}
706
 
707
proc_6:
708
        ; On entry:
709
        ;       R0 = ev
710
        ;       R1 = ep
711 69 dgisselq
        ;       R2 = link address
712 41 dgisselq
        ; Since we call func_3, we have to reserve R0 and R1
713
        ; for other purposes.  Thus
714
        ;       R2 = ev
715
        ;       R3 = ep
716
        SUB     2,SP
717 69 dgisselq
        STO     R2,(SP)
718
        STO     R3,1(SP)
719 41 dgisselq
 
720
        MOV     R1,R3
721
        MOV     R0,R2
722
        ; *ep = ev
723
        STO     R0,(R1)
724
#ifndef SKIP_SHORT_CIRCUITS
725
        CMP     2,R0
726
        BUSY.NZ
727
#endif
728
 
729
#ifdef  NO_INLINE
730
        ; !func_3(ev)
731 69 dgisselq
        MOV     __HERE__+2(PC),R1
732 41 dgisselq
        BRA     func_3
733
 
734
        TST     -1,R0
735
        LDI     3,R1
736 69 dgisselq
#ifndef SKIP_SHORT_CIRCUITS
737
        BUSY.Z
738
#endif
739 41 dgisselq
        STO.Z   R1,(R3)
740
#else
741 69 dgisselq
        CMP     2,R0
742 41 dgisselq
        LDI     3,R1
743 74 dgisselq
#ifndef SKIP_SHORT_CIRCUITS
744 69 dgisselq
        BUSY.NZ
745 41 dgisselq
#endif
746 69 dgisselq
        STO.NZ  R1,(R3)
747 41 dgisselq
#endif
748
 
749
#ifndef SKIP_SHORT_CIRCUITS
750
        CMP     2,R2
751
        BUSY.NZ
752
#endif
753
        CMP     0,R2
754
        BNZ     proc_6_case_not_zero
755
#ifndef SKIP_SHORT_CIRCUITS
756
        BUSY
757
#endif
758
        LDI     0,R1
759
        STO     R1,(R3)
760
        BRA     proc_6_end_of_case
761
proc_6_case_not_zero:
762
        CMP     1,R2
763
        BNZ     proc_6_case_not_one
764
#ifndef SKIP_SHORT_CIRCUITS
765
        BUSY
766
#endif
767
        LDI     3,R0
768
        LOD     gbl_int(R12),R1
769
        CMP     100,R1
770
        CLR.GT  R0
771
        STO     R0,(R3)
772
        BRA     proc_6_end_of_case
773
proc_6_case_not_one:
774
        CMP     2,R2
775
        BNZ     proc_6_case_not_two
776
        LDI     1,R1                            // Executed, if done properly
777
        STO     R1,(R3)
778
        BRA     proc_6_end_of_case
779
proc_6_case_not_two:
780
#ifndef SKIP_SHORT_CIRCUITS
781 74 dgisselq
        NOOP                            ;;;;;;;; TODO This fails--needs the NOOP
782
        BUSY                            ;;;;;;;; TODO so as not to do the BUSY
783 41 dgisselq
#endif
784
        CMP     4,R2
785
        BNZ     proc_6_case_not_four
786
        LDI     2,R1
787
        STO     R1,(R3)
788
        // BRA  proc_6_end_of_case
789
proc_6_case_not_four:
790
proc_6_end_of_case:
791 69 dgisselq
        LOD     (SP),R2
792
        LOD     1(SP),R3
793 74 dgisselq
#ifndef SKIP_SHORT_CIRCUITS
794
        CMP     LOAD_ADDRESS,R2         ; TODO This fails, even when the address
795
        BUSY.LT
796
#endif
797 41 dgisselq
        ADD     2,SP
798 69 dgisselq
        JMP     R2
799 41 dgisselq
 
800
// void proc_7(int a, int b, int *c) {
801
//      int     lcl;
802
//
803
//      lcl = a + 2;
804
//      *c = b + a;
805
//}
806
 
807
#ifdef  NO_INLINE
808
proc_7:
809
        ADD 2+R0,R1
810
        STO R1,(R2)
811
 
812 74 dgisselq
#ifndef SKIP_SHORT_CIRCUITS
813
        CMP     LOAD_ADDRESS,R3
814
        BUSY.LT
815
#endif
816 69 dgisselq
        JMP     R3
817 41 dgisselq
#endif
818
 
819
//      int     a[50];
820
//      int     b[50][50];
821
//
822
// void proc_8(Arr_1_Dim a, Arr_2_Dim b, int c, int d) {
823
//      int     idx, loc;
824
//
825
//      loc = c+5;
826
//      a[loc] = d;
827
//      a[loc+1] = a[loc];
828
//      a[loc+30] = loc;
829
//      for(idx=loc; idx<= loc+1; idx++)
830
//              b[loc][idx] = loc;
831
//      b[loc][loc-1] += 1;
832
//      b[loc+20][loc] = a[loc];
833
//      gbl_int = 5;
834
//}
835
proc_8:
836
        ; R0 = a
837
        ; R1 = b
838
        ; R2 = c
839
        ; R3 = d
840
        ; R4 - unassigned
841
        ; Makes no function/procedure calls, so these can keep
842
        ; R2 = loc = c+5, replaces c
843
        ; R4 = idx
844 69 dgisselq
        SUB     3,SP
845
        STO     R4,(SP)
846 41 dgisselq
        STO     R5,1(SP)
847
        STO     R6,2(SP)
848
 
849
        ADD     5,R2    ; loc = c+5
850
        MOV     R0,R5
851
        ADD     R2,R5
852
        STO     R3,(R5)
853
        STO     R3,1(R5)
854
        STO     R2,30(R5)
855
        MOV     R2,R5
856 152 dgisselq
        MPY     50,R5   ; R5 = 50 * R2 = 50 * loc
857 41 dgisselq
        ADD     R1,R5   ; R5 = &b[loc][0]
858
        MOV     R5,R6   ; R6 = &b[loc][0]
859
        ADD     R2,R5   ; R5 = &b[loc][loc]
860
        MOV     R2,R4   ; R4 = loc = index
861
proc_8_top_of_loop:
862
        CMP     1(R2),R4
863
        BGT     proc_8_end_of_loop
864
proc_8_loop_after_condition:
865
        STO     R2,(R5)
866
        ADD     1,R5
867
        ADD     1,R4
868
        CMP     2(R2),R4
869
        BLT     proc_8_loop_after_condition
870
proc_8_end_of_loop:
871
 
872
        ; b[loc][loc-1] += 1
873
        ADD     R2,R6           ; R6 = &b[loc][loc]
874
        LOD     -1(R6),R5
875
        ADD     1,R5
876
        STO     R5,-1(R6)
877
        ; b[loc+20][loc] = a[loc]
878
        MOV     R0,R4
879
        ADD     R2,R4
880
        LOD     (R4),R3
881
        STO     R3,20*50(R6)
882
        LDI     5,R3
883
        STO     R3,gbl_int(R12)
884
 
885 69 dgisselq
        LOD     (SP),R4
886 41 dgisselq
        LOD     1(SP),R5
887
        LOD     2(SP),R6
888 69 dgisselq
        ADD     3,SP
889 74 dgisselq
#ifndef SKIP_SHORT_CIRCUITS
890
        CMP     LOAD_ADDRESS,R4
891
        BUSY.LT
892
#endif
893 69 dgisselq
        JMP     R4
894 41 dgisselq
 
895
// void proc_5(void) {
896
//      gbl_ch = 'A';
897
//      gbl_bool = false;
898
//}
899
#ifdef  NO_INLINE
900
proc_5:
901 69 dgisselq
        SUB     1,SP
902
        STO     R0,(SP)
903
        ;
904 41 dgisselq
        LDI     'A',R0
905
        STO     R0,gbl_ch(R12)
906
        CLR     R0
907
        STO     R0,gbl_bool(R12)
908
        ;
909 69 dgisselq
        LOD     (SP),R0
910
        ADD     1,SP
911
        JMP     R0
912 41 dgisselq
#endif
913
 
914
// void proc_4(void) {
915
//      bool    lcl_bool;
916
//      lcl_bool = (gbl_ch == 'A');
917
//      gbl_ch_2 = 'B';
918
// }
919
#ifdef  NO_INLINE
920
proc_4:
921
        //
922
        ; LDI   GBL,R12 // Already in R12
923
        ; Setting lcl_bool is irrelevant, so the optimizer should remove it.
924
        ; R0 doesn't need to be saved, since it's already trashed by the
925
        ; subroutine call.
926
        ;
927
        ; LOD   gbl_ch(R12),R0
928
        ; CLR   R1
929
        ; CMP   'A',R0
930
        ; ADD.Z 1,R1
931
        ;
932 69 dgisselq
        SUB     1,SP
933
        STO     R0,(SP)
934
        ;
935 41 dgisselq
        LDI     'B',R0
936
        STO     R0,gbl_ch_2(R12)
937
        ;
938 69 dgisselq
        LOD     (SP),R0
939
        ADD     1,SP
940
        JMP     R0
941 41 dgisselq
#endif
942
 
943
// void proc_3(RECP *a) {
944
//      if (gbl_ptr != NULL)
945
//              *a = gbl_ptr->ptr_comp;
946
//      proc_7(10,gbl_int, &gbl_ptr->variant.var_1.int_comp); // ??
947
//}
948
proc_3:
949
        SUB     3,SP
950 69 dgisselq
        STO     R1,(SP)
951
        STO     R2,1(SP)
952 41 dgisselq
        STO     R3,2(SP)
953
        ;
954
        LOD     gbl_ptr(R12),R2
955
        TST     -1,R2
956
#ifndef SKIP_SHORT_CIRCUITS
957
        BUSY.Z
958
#endif
959
        LOD.NZ  ptr_comp(R2),R3
960
        STO.NZ  R3,(R0)
961
#ifdef  NO_INLINE
962
        LDI     10,R0
963
        LOD     gbl_int(R12),R1
964
        MOV     variant.var_1.int_comp(R2),R2
965 69 dgisselq
        MOV     __HERE__+2(PC),R3
966 41 dgisselq
        BRA     proc_7
967
#else
968
        LOD     gbl_int(R12),R1
969
        ADD      12,R1
970
        STO      R1,variant.var_1.int_comp(R2)
971
#endif
972
        ;
973 69 dgisselq
        LOD     (SP),R1
974
        LOD     1(SP),R2
975 41 dgisselq
        LOD     2(SP),R3
976
        ADD     3,SP
977 74 dgisselq
#ifndef SKIP_SHORT_CIRCUITS
978
        CMP     LOAD_ADDRESS,R1
979
        BUSY.LT
980
#endif
981 69 dgisselq
        JMP     R1
982 41 dgisselq
 
983
// void proc_2(int *a) {
984
//      int             lcl_int;
985
//      test_enum       lcl_enum;
986
//
987
//      lcl_int = *a + 10;
988
//      do {
989
//              if (gbl_ch == 'A') {
990
//                      lcl_int -= 1;
991
//                      *a = lcl_int - gbl_int;
992
//                      lcl_enum = Ident_1;
993
//              }
994
//      } while(lcl_enum != Ident_1);
995
//}
996
proc_2:
997 69 dgisselq
        SUB     6,SP
998
        STO     R1,(SP)
999
        STO     R2,1(SP)
1000
        STO     R3,2(SP)
1001 41 dgisselq
        STO     R4,3(SP)
1002 69 dgisselq
        STO     R5,4(SP)
1003
        STO     R6,5(SP)
1004 41 dgisselq
        // R1 doesn't need to be stored, it was used in the subroutine
1005
        // call calculation
1006
 
1007
        LOD     (R0),R1
1008
        MOV     10(R1),R2       ; R2 = lcl_int
1009
        LOD     gbl_ch(R12),R4  ; R4 = gbl_ch
1010
#ifdef  NO_CHEATING
1011
proc_2_loop:
1012
        CMP     'A',R4
1013
        SUB.Z   1,R2
1014
        LOD.Z   gbl_int(R12),R5 ; R5 = gbl_int
1015
        MOV.Z   R2,R6           ; R6 = lcl_int
1016
        SUB.Z   R5,R6           ; lcl_int - gbl_int
1017
        STO.Z   R6,(R0)         ; *a = R6
1018
        CLR.Z   R3              ; lcl_enum = 0
1019
// #ifndef      SKIP_SHORT_CIRCUITS
1020
        // BUSY.NZ
1021
// #endif
1022
 
1023
        TST     -1,R3
1024
// #ifndef      SKIP_SHORT_CIRCUITS
1025
        // BUSY.NZ
1026
// #endif
1027
        BNZ     proc_2_loop
1028
#else
1029
        LOD     gbl_int(R12),R5
1030
        SUB     1(R5),R2
1031
        STO     R2,(R0)
1032
#endif
1033
        ;
1034 69 dgisselq
        LOD     (SP),R1
1035
        LOD     1(SP),R2
1036
        LOD     2(SP),R3
1037 41 dgisselq
        LOD     3(SP),R4
1038 69 dgisselq
        LOD     4(SP),R5
1039
        LOD     5(SP),R6
1040
        ADD     6,SP
1041 74 dgisselq
#ifndef SKIP_SHORT_CIRCUITS
1042
        CMP     LOAD_ADDRESS,R1
1043
        BUSY.LT
1044
#endif
1045 69 dgisselq
        JMP     R1
1046 41 dgisselq
 
1047
//void  proc_1 (RECP a) {
1048
//      RECP    nxt = a->ptr_comp;
1049
//
1050
//      // structassign(a->ptr_comp, gbl_ptr);
1051
//      *(a->ptr_comp) = *(gbl_ptr);
1052
//
1053
//      a->variant.var_1.int_comp = 5;
1054
//      nxt->variant.var_1.int_comp = a->variant.var_1.int_comp;
1055
//      proc_3(&nxt->ptr_comp);
1056
//
1057
//      if (nxt->discr == 0) {
1058
//              nxt->variant.var_1.int_comp = 6;
1059
//              proc_6(a->variant.var_1.enum_comp, &nxt->variant.var_1.enum_comp);
1060
//              nxt->ptr_comp = gbl_ptr->ptr_comp;
1061
//              proc_7(nxt->variant.var_1.int_comp, 10, &nxt->variant.var_1.int_comp);
1062
//      } else
1063
//              // structassign(a, a->ptr_comp);
1064
//              *a = *(a->ptr_comp);
1065
//}
1066
proc_1:
1067 69 dgisselq
        SUB     11,SP
1068
        STO     R1,(SP)
1069
        STO     R2,1(SP)
1070
        STO     R3,2(SP)
1071
        STO     R4,3(SP)
1072
        STO     R5,4(SP)
1073
        STO     R6,5(SP)
1074
        STO     R7,6(SP)
1075
        STO     R8,7(SP)
1076
        STO     R9,8(SP)
1077
#ifndef NO_LOOP_UNROLLING
1078
        STO     R10,9(SP)
1079
        STO     R11,10(SP)
1080
#endif
1081 41 dgisselq
 
1082
        ; R9 = a
1083
        ; R4 = nxt
1084
        ; R12 = GBL
1085
        ; R13 = SP
1086
        MOV     R0,R9
1087
        LOD     ptr_comp(R9),R4
1088
#ifndef SKIP_SHORT_CIRCUITS
1089 74 dgisselq
        TST     -1,R4           ; R4 = 0x100e9f
1090 41 dgisselq
        BUSY.Z
1091 74 dgisselq
        CMP     PC,R9           ; R9 = 0x100ec2
1092 69 dgisselq
        BUSY.LT
1093 41 dgisselq
#endif
1094
        MOV     R9,R6
1095 74 dgisselq
        LOD     gbl_ptr(R12),R7 ; (0x100a04) -> 0x100ec2
1096
        ; BUSY                  ; R7 = 0x0100ec2
1097 69 dgisselq
 
1098
#ifndef SKIP_SHORT_CIRCUITS
1099
        LOD     variant.var_1.enum_comp(R7), R0
1100 74 dgisselq
        CMP     2,R0            ; R0 = 0
1101
        BUSY.NZ                 ; TODO Fails here
1102 69 dgisselq
#endif
1103
 
1104
#ifdef  NO_LOOP_UNROLLING
1105
        LDI     35,R5
1106 41 dgisselq
proc_1_assign_loop_1:
1107
        LOD     (R6),R8
1108
        ADD     1,R6
1109
        STO     R8,(R7)
1110
        ADD     1,R7
1111
        SUB     1,R5
1112
        BNZ     proc_1_assign_loop_1;
1113 69 dgisselq
#else
1114 41 dgisselq
 
1115 69 dgisselq
        ; R2 is available
1116
        ; R3 is available
1117
 
1118
        LDI     34,R5
1119
proc_1_assign_loop_1:
1120
        LOD     (R6),R8
1121
        LOD     1(R6),R10
1122
        LOD     2(R6),R11
1123
        LOD     3(R6),R2
1124
        LOD     4(R6),R3
1125
        ADD     5,R6
1126
        SUB     5,R5
1127
        STO     R8,(R7)
1128
        STO     R10,1(R7)
1129
        STO     R11,2(R7)
1130
        STO     R2,3(R7)
1131
        STO     R3,4(R7)
1132
        BLT     proc_1_assign_loop_1_end
1133
        ADD     5,R7
1134
        ; BNZ   proc_1_assign_loop_1;
1135
        BRA     proc_1_assign_loop_1
1136
proc_1_assign_loop_1_end:
1137
        ; Loop length is fixed, nothing to test here
1138
#endif
1139
 
1140 41 dgisselq
#ifndef SKIP_SHORT_CIRCUITS
1141
        LOD     gbl_ptr(R12),R2
1142
        TST     -1,R2
1143
        BUSY.Z
1144 69 dgisselq
        ;
1145
        LOD     variant.var_1.enum_comp(R9), R0
1146
        CMP     2,R0
1147
        BUSY.NZ
1148 41 dgisselq
#endif
1149
 
1150
        LDI     5,R5
1151
        STO     R5,variant.var_1.int_comp(R9)
1152
        STO     R5,variant.var_1.int_comp(R4)
1153 74 dgisselq
        MOV     ptr_comp(R4),R0                 ; R4 = 0x8e41, ptr_comp(R4)=R4
1154 69 dgisselq
        MOV     __HERE__+2(PC),R1
1155 41 dgisselq
        BRA     proc_3          ; Uses R0 and R1
1156
 
1157
        LOD     discr(R4),R5
1158
        CMP     0,R5
1159
        BNZ     proc_1_last_struct_assign
1160
        ; This is the juncture that is "supposed" to be taken
1161
        LDI     6,R5
1162
 
1163
        STO     R5,variant.var_1.int_comp(R4)
1164
        LOD     variant.var_1.enum_comp(R9), R0
1165
#ifndef SKIP_SHORT_CIRCUITS
1166
        CMP     2,R0
1167
        BUSY.NZ
1168
#endif
1169
        MOV     variant.var_1.enum_comp+R4, R1
1170 69 dgisselq
        MOV     __HERE__+2(PC),R2
1171 41 dgisselq
        BRA     proc_6
1172
        ;
1173
        LOD     gbl_ptr(R12),R5
1174 74 dgisselq
        LOD     ptr_comp(R5),R5
1175 41 dgisselq
        STO     R5,ptr_comp(R4)
1176
        ;
1177
#ifdef  NO_INLINE
1178
        LOD     variant.var_1.int_comp(R4),R0
1179
        LDI     10,R1
1180
        MOV     variant.var_1.int_comp(R4),R2
1181
        MOV     proc_1_return_closeout(PC),R3
1182
        BRA     proc_7
1183
#else
1184
        LOD     variant.var_1.int_comp(R4),R0
1185
        ADD     12,R0
1186
        STO     R0,variant.var_1.int_comp(R4)
1187
        BRA     proc_1_return_closeout
1188
#endif
1189
        ;
1190
proc_1_last_struct_assign:
1191
#ifndef SKIP_SHORT_CIRCUITS
1192
        BUSY
1193
#endif
1194
        LDI     35,R4
1195
        MOV     R2,R5
1196
        LOD     gbl_ptr(R12),R6
1197
proc_1_assign_loop_2:
1198
        LOD     (R6),R8
1199
        STO     R8,(R7)
1200
        ADD     1,R6
1201
        ADD     1,R7
1202
        SUB     1,R5
1203
        BNZ     proc_1_assign_loop_2
1204
        //
1205
proc_1_return_closeout:
1206
        //
1207 69 dgisselq
        LOD     (SP),R1
1208
        LOD     1(SP),R2
1209
        LOD     2(SP),R3
1210
        LOD     3(SP),R4
1211
        LOD     4(SP),R5
1212
        LOD     5(SP),R6
1213
        LOD     6(SP),R7
1214
        LOD     7(SP),R8
1215
        LOD     8(SP),R9
1216
#ifndef NO_LOOP_UNROLLING
1217
        LOD     9(SP),R10
1218
        LOD     10(SP),R11
1219
#endif
1220
        ADD     11,SP
1221 74 dgisselq
#ifndef SKIP_SHORT_CIRCUITS
1222
        CMP     LOAD_ADDRESS,R1
1223
        BUSY.LT
1224
#endif
1225 69 dgisselq
        JMP     R1              // Jumps to wrong address ??
1226 41 dgisselq
 
1227
// void dhrystone(void) {
1228
//      int     lcl_int_1, lcl_int_2, lcl_int_3, index, number_of_runs = 500;
1229
//      test_enum       lcl_enum;
1230
//      char    lcl_str_1[30], lcl_str_2[30], ch_index;
1231
//      REC_T   a, b, *nxt = &a;
1232
//
1233
//      gbl_ptr = &b;
1234
//      gbl_ptr->ptr_comp = nxt;
1235
//      gbl_ptr->variant.var_1.enum_comp = 2;
1236
//      gbl_ptr->variant.var_1.int_comp = 40;
1237
//      lcl_strcpy(gbl_ptr->variant.var_1.str_comp, "DHRYSTONE PROGRAM, SOME STRING");
1238
//      lcl_strcpy(lcl_str_1, "DHRYSTONE PROGRAM, 1\'ST STRING");
1239
//
1240
//      gbl_arr_2[8][7] = 10;
1241
//
1242
//      for(index=0; index < number_of_runs; index++) {
1243
//              proc_5();
1244
//              proc_4();
1245
//              lcl_int_1 = 2;
1246
//              lcl_int_2 = 3;
1247
//              lcl_strcpy(lcl_str_2, "DHRYSTONE PROGRAM, 2\'ND STRING");
1248
//              lcl_enum = Ident_2;
1249
//              gbl_bool = !func_2(lcl_str_1, lcl_str_2);
1250
//              while(lcl_int_1 < lcl_int_2) {
1251
//                      lcl_int_3 = 5 * lcl_int_1 - lcl_int_2;
1252
//                      proc_7(lcl_int_1, lcl_int_2, &lcl_int_3);
1253
//                      lcl_int_1 += 1;
1254
//              }
1255
//
1256
//              proc_8(gbl_arr_1, gbl_arr_2, lcl_int_1, lcl_int_3);
1257
//              proc_1(gbl_ptr);
1258
//
1259
//              for(ch_index='A'; ch_index <= gbl_ch_2; ch_index++) {
1260
//                      if (lcl_enum == func_1(ch_index, 'C')) {
1261
//                              // Then not executed??
1262
//                              proc_6(0, &lcl_enum);
1263
//                              lcl_strcpy(lcl_str_2, "DHRYSTONE PROGRAM, 3\'RD STRING");
1264
//                              lcl_int_2 = index;
1265
//                              gbl_int = index;
1266
//                      }
1267
//              }
1268
//
1269
//              lcl_int_2 = lcl_int_2 * lcl_int_1;
1270
//              lcl_int_1 = lcl_int_2 / lcl_int_3;
1271
//              lcl_int_2 = 7 * ( lcl_int_2 - lcl_int_3) - lcl_int_1;
1272
//              proc_2(&lcl_int_1);
1273
//      }
1274
//}
1275
 
1276
dhrystone:
1277
#ifdef  SUPERVISOR_TASK
1278
        SUB     12+RECSIZE+RECSIZE+30+30+3,SP
1279
        ; Leave a space on the top of the stack for calling
1280
        ; subroutines.
1281 69 dgisselq
        STO     R0,(SP)
1282
        STO     R1,1(SP)
1283
        STO     R2,2(SP)
1284
        STO     R3,3(SP)
1285
        STO     R4,4(SP)
1286
        STO     R5,5(SP)
1287
        STO     R6,6(SP)
1288
        STO     R7,7(SP)
1289
        STO     R8,8(SP)
1290
        STO     R9,9(SP)
1291
        STO     R10,10(SP)
1292
        STO     R11,11(SP)
1293 41 dgisselq
        lcl_int_1       equ     12                      ; plus SP
1294
#else
1295
        lcl_int_1       equ     2                       ; plus SP
1296
        SUB     2+RECSIZE+RECSIZE+30+30+3,SP
1297
#endif
1298
        // 12 is the global variable pointer
1299
        // 13 is our stack
1300
        // 14 is our condition code register
1301
        // 15 is the program counter
1302
        ;
1303
        lcl_int_3       equ     lcl_int_1+1             ; plus SP
1304
        lcl_enum        equ     lcl_int_3+1             ; plus SP
1305
        lcl_str_1       equ     lcl_enum+1              ; plus SP
1306
        lcl_str_2       equ     lcl_str_1+30            ; plus SP
1307
        rec_a           equ     lcl_str_2+30            ; plus SP
1308
        rec_b           equ     rec_a+RECSIZE           ; plus SP
1309
 
1310
//      int     lcl_int_1, lcl_int_2, lcl_int_3, index, number_of_runs = 500;
1311
//      test_enum       lcl_enum;
1312
//      char    lcl_str_1[30], lcl_str_2[30], ch_index;
1313
//      REC_T   a, b, *nxt = &a;
1314
//
1315
//      gbl_ptr = &b;
1316
        MOV     rec_b(SP),R0            ; R0 = &b
1317
        STO     R0,gbl_ptr(PC)
1318
//      gbl_ptr->ptr_comp = nxt;
1319
        MOV     rec_a(SP),R1            ; R1 = &a = nxt
1320
        STO     R1,ptr_comp(R0)         ; gbp_ptr->ptr.comp=b->ptr.comp=R1=nxt
1321
//      gbl_ptr->variant.var_1.enum_comp = 2;
1322
        LDI     2,R2
1323
        STO     R2,variant.var_1.enum_comp(R0)
1324
//      gbl_ptr->variant.var_1.int_comp = 40;
1325
        LDI     40,R2
1326
        STO     R2,variant.var_1.int_comp(R0)
1327
//      lcl_strcpy(gbl_ptr->variant.var_1.str_comp, "DHRYSTONE PROGRAM, SOME STRING");
1328
        MOV     variant.var_1.str_comp(R0),R0
1329
        MOV     some_string(PC),R1
1330 69 dgisselq
        MOV     __HERE__+2(PC),R2
1331 41 dgisselq
        BRA     lcl_strcpy
1332
 
1333
//      lcl_strcpy(lcl_str_1, "DHRYSTONE PROGRAM, 1\'ST STRING");
1334
        MOV     lcl_str_1(SP),R0
1335
        MOV     first_string(PC),R1
1336 69 dgisselq
        MOV     __HERE__+2(PC),R2
1337 41 dgisselq
        BRA     lcl_strcpy
1338
 
1339
//      gbl_arr_2[8][7] = 10;
1340
        LDI     10,R0
1341
        STO     R0,8*50+7+gbl_arr_2(R12)
1342
//
1343
//      for(index=0; index < number_of_runs; index++) {
1344
        ; Let R11 be our index
1345
        CLR     R11
1346
dhrystone_main_loop:
1347
        ;; Start of Dhrystone main loop
1348
        ; proc_5();
1349
#ifdef  NO_INLINE
1350 69 dgisselq
        MOV     __HERE__+2(PC),R0
1351 41 dgisselq
        BRA     proc_5
1352
#else
1353
        LDI     'A',R0
1354
        STO     R0,gbl_ch(R12)
1355
        CLR     R0
1356
        STO     R0,gbl_bool(R12)
1357
#endif
1358
        ; proc_4();
1359
#ifdef  NO_INLINE
1360 69 dgisselq
        MOV     __HERE__+2(PC),R0
1361 41 dgisselq
        BRA     proc_4
1362
#else
1363
        LDI     'B',R0
1364
        STO     R0,gbl_ch_2(R12)
1365
#endif
1366
//              lcl_int_1 = 2;
1367
        LDI     2,R5
1368
        STO     R5,lcl_int_1(SP)
1369
//              lcl_int_2 = 3;
1370
        LDI     3,R6
1371
//              lcl_strcpy(lcl_str_2, "DHRYSTONE PROGRAM, 2\'ND STRING");
1372
        MOV     lcl_str_2(SP),R0
1373
        MOV     second_string(PC),R1
1374 69 dgisselq
        MOV     __HERE__+2(PC),R2
1375 41 dgisselq
        BRA     lcl_strcpy
1376
//              lcl_enum = Ident_2;
1377
        LDI     2,R0
1378
        STO     R0,lcl_enum(SP)
1379
//              gbl_bool = !func_2(lcl_str_1, lcl_str_2);
1380
        MOV     lcl_str_1(SP),R0
1381
        MOV     lcl_str_2(SP),R1
1382 69 dgisselq
        MOV     __HERE__+2(PC),R2
1383 41 dgisselq
        BRA     func_2
1384
        CLR     R1
1385
        TST     -1,R0
1386
        LDILO.Z 1,R1
1387
        STO     R1,gbl_bool(PC)
1388
 
1389
//              while(lcl_int_1 < lcl_int_2) {
1390
        ; R5 = lcl_int_1 = 2 on entry
1391
        ; R6 = lcl_int_2 = 3 on entry, so no entry test is required
1392
        LOD     lcl_int_1(SP),R5
1393
        // The 'while' comparison
1394
        CMP     R6,R5
1395
        BGE     dhrystone_end_while_loop
1396
dhrystone_while_loop:
1397
//                      lcl_int_3 = 5 * lcl_int_1 - lcl_int_2;
1398
        MOV     R5,R7
1399 152 dgisselq
        MPY     5,R7
1400 41 dgisselq
        SUB     R6,R7
1401
        STO     R7,lcl_int_3(SP)
1402 69 dgisselq
#ifndef SKIP_SHORT_CIRCUITS
1403
        CMP     7,R7
1404
        BUSY.NZ
1405
#endif
1406 41 dgisselq
//                      proc_7(lcl_int_1, lcl_int_2, &lcl_int_3);
1407
#ifdef  NO_INLINE
1408
        MOV     R5,R0
1409
        MOV     R6,R1
1410
        MOV     lcl_int_3(SP),R2
1411 69 dgisselq
        MOV     __HERE__+2(PC),R3
1412 41 dgisselq
        BRA     proc_7
1413
#else
1414
        MOV     R6,R1
1415
        ADD     2+R5,R1
1416
        STO     R1,lcl_int_3(SP)
1417
#endif
1418
//                      lcl_int_1 += 1;
1419
        LOD     lcl_int_1(SP),R5
1420
        ADD     1,R5
1421
        STO     R5,lcl_int_1(SP)
1422
;
1423
        ; BRA   dhrystone_while_loop    ; We'll unroll the loop, and put an
1424
        CMP     R6,R5                   ; additional comparison at the bottom
1425
        BLT     dhrystone_while_loop
1426
dhrystone_end_while_loop:
1427
//              }
1428
//
1429 69 dgisselq
#ifndef SKIP_SHORT_CIRCUITS
1430
        LOD     lcl_int_1(SP),R0
1431
        CMP     3,R0
1432
        BUSY.NZ
1433
        CMP     3,R6
1434 74 dgisselq
        BUSY.NZ
1435 69 dgisselq
        LOD     lcl_int_3(SP),R0
1436
        CMP     7,R0
1437
        BUSY.NZ
1438
#endif
1439 41 dgisselq
//              proc_8(gbl_arr_1, gbl_arr_2, lcl_int_1, lcl_int_3);
1440
        MOV     gbl_arr_1(PC),R0
1441
        MOV     gbl_arr_2(PC),R1
1442
        MOV     R5,R2
1443
        MOV     R6,R3
1444 69 dgisselq
        MOV     __HERE__+2(PC),R4
1445 41 dgisselq
        BRA     proc_8
1446
//              proc_1(gbl_ptr);
1447
        LOD     gbl_ptr(PC),R0
1448 74 dgisselq
#ifndef SKIP_SHORT_CIRCUITS
1449
        LOD     variant.var_1.enum_comp(R0), R1
1450
        CMP     2,R1            ; R0 = 0
1451
        BUSY.NZ                 ; TODO Fails here
1452
#endif
1453 69 dgisselq
        MOV     __HERE__+2(PC),R1
1454 41 dgisselq
        BRA     proc_1
1455
//
1456
//              for(ch_index='A'; ch_index <= gbl_ch_2; ch_index++) {
1457
        LDI     'A',R7
1458
        LOD     gbl_ch_2(SP),R8
1459
        CMP     R7,R8
1460
        BLT     dhrystone_end_of_for_loop
1461
dhrystone_top_of_for_loop:
1462
//                      if (lcl_enum == func_1(ch_index, 'C')) {
1463
#ifdef  NO_INLINE
1464
        MOV     R7,R0
1465
        LDI     'C',R1
1466 69 dgisselq
        MOV     __HERE__+2(PC),R2
1467 41 dgisselq
        BRA     func_1
1468
#else
1469
        CMP     'C',R7
1470
        CLR.NZ  R0
1471
        STO.Z   R7,gbl_ch(R12)
1472
        LDILO.Z 1,R0
1473
#endif
1474
 
1475
        ; Result is now in R0
1476
        LOD     lcl_enum(SP),R1
1477
        CMP     R0,R1
1478
        BNZ     dhrystone_skip_then_clause
1479
//                              // Then not executed??
1480
//                              proc_6(0, &lcl_enum);
1481
 
1482
#ifndef SKIP_SHORT_CIRCUITS
1483 69 dgisselq
        BUSY    // Shouldn't ever get here
1484 41 dgisselq
#endif
1485
 
1486
        CLR     R0
1487
        MOV     lcl_enum(SP),R1
1488 69 dgisselq
        MOV     __HERE__+2(PC),R2
1489 41 dgisselq
        BRA     proc_6
1490
 
1491
//                              lcl_strcpy(lcl_str_2, "DHRYSTONE PROGRAM, 3\'RD STRING");
1492
        MOV     lcl_str_2(SP),R0
1493
        MOV     third_string(PC),R1
1494 69 dgisselq
        MOV     __HERE__+2(PC),R2
1495 41 dgisselq
        BRA     lcl_strcpy
1496
//                              lcl_int_2 = index;
1497
        MOV     R11,R6
1498
//                              gbl_int = index;
1499
        STO     R11,gbl_int(PC)
1500
//                      }
1501
dhrystone_skip_then_clause:
1502
        ADD     1,R7
1503
        LOD     gbl_ch_2(SP),R8
1504
        CMP     R8,R7
1505
        BGE     dhrystone_top_of_for_loop
1506
dhrystone_end_of_for_loop:
1507
//              }
1508 69 dgisselq
#ifndef SKIP_SHORT_CIRCUITS
1509
        LOD     lcl_int_1(SP),R0
1510
        CMP     3,R0
1511
        BUSY.NZ
1512
        CMP     3,R6
1513
        BUSY.NZ
1514
        LOD     lcl_int_3(SP),R0
1515
        CMP     7,R0
1516
        BUSY.NZ
1517
#endif
1518 41 dgisselq
//
1519
//              lcl_int_2 = lcl_int_2 * lcl_int_1;
1520
        LOD     lcl_int_1(SP),R5
1521 152 dgisselq
        MPY     R5,R6   ; lcl_int_2 =
1522 41 dgisselq
//              lcl_int_1 = lcl_int_2 / lcl_int_3;
1523 69 dgisselq
#ifdef  HARDWARE_DIVIDE
1524
        LOD     lcl_int_3(SP),R1
1525
        MOV     R6,R0
1526
        DIVS    R1,R0
1527
#else
1528 41 dgisselq
#ifndef SKIP_DIVIDE
1529
        MOV     R6,R0
1530
        LOD     lcl_int_3(SP),R1
1531 69 dgisselq
        MOV     __HERE__+2(PC),R2
1532
        BRA     lib_divs
1533 41 dgisselq
#else
1534
        LDI     9,R0
1535
#endif
1536 69 dgisselq
#endif
1537 74 dgisselq
        STO     R0,lcl_int_1(SP)        ;;; TODO FAILS HERE (Watched it fail!)
1538 41 dgisselq
//              lcl_int_2 = 7 * ( lcl_int_2 - lcl_int_3) - lcl_int_1;
1539
        LOD     lcl_int_3(SP),R2
1540
        SUB     R2,R6
1541 152 dgisselq
        MPY     7,R6
1542 41 dgisselq
        SUB     R0,R6
1543
//              proc_2(&lcl_int_1);
1544 69 dgisselq
#ifndef SKIP_SHORT_CIRCUITS
1545
        LOD     lcl_int_1(SP),R0
1546
        CMP     1,R0
1547 74 dgisselq
        CMP.Z   13,R6
1548
        LOD.Z   lcl_int_3(SP),R0
1549
        CMP.Z   7,R0
1550
        BZ      dhrystone_triple_test_still_good
1551
        BUSY
1552
dhrystone_triple_test_still_good:
1553 69 dgisselq
#endif
1554 41 dgisselq
        MOV     lcl_int_1(SP),R0
1555 69 dgisselq
        MOV     __HERE__+2(PC),R1
1556 41 dgisselq
        BRA     proc_2
1557 69 dgisselq
#ifndef SKIP_SHORT_CIRCUITS
1558
        LOD     lcl_int_1(SP),R0
1559
        CMP     5,R0
1560
        BUSY.NZ
1561
#endif
1562 41 dgisselq
 
1563
        ;; Bottom of (and return from) Dhrystone main loop
1564
        ADD     1,R11
1565
        CMP     NUMBER_OF_RUNS,R11
1566
        BLT     dhrystone_main_loop
1567
//      }
1568
 
1569
#ifdef  SUPERVISOR_TASK
1570 69 dgisselq
        LOD     (SP),R0
1571
        LOD     1(SP),R1
1572
        LOD     2(SP),R2
1573
        LOD     3(SP),R3
1574
        LOD     4(SP),R4
1575
        LOD     5(SP),R5
1576
        LOD     6(SP),R6
1577
        LOD     7(SP),R7
1578
        LOD     8(SP),R8
1579
        LOD     9(SP),R9
1580
        LOD     10(SP),R10
1581
        LOD     11(SP),R11
1582 41 dgisselq
        ;
1583
        ADD     12+RECSIZE+RECSIZE+30+30+3,SP
1584
        ; Return from subroutine
1585 74 dgisselq
#ifndef SKIP_SHORT_CIRCUITS
1586
        CMP     LOAD_ADDRESS,R0
1587
        BUSY.LT
1588
#endif
1589 69 dgisselq
        JMP     R0
1590 41 dgisselq
#else
1591
        LDI     0,CC
1592
        NOP
1593
        NOP
1594
        BUSY
1595
#endif
1596 74 dgisselq
gbl_arr_1:
1597
        fill    50,0
1598
gbl_arr_2:
1599
        fill    2500,0
1600
gbl_ch:
1601
        word    0
1602
gbl_ch_2:
1603
        word    0
1604
gbl_bool:
1605
        word    0
1606
gbl_int:
1607
        word    0
1608
gbl_ptr:
1609
        word    0
1610
 
1611
some_string:
1612
        word    'D','H','R','Y','S','T','O','N','E',' '
1613
        word    'P','R','O','G','R','A','M',',',' '
1614
        word    'S','O','M','E',' ','S','T','R','I','N','G'
1615
        word    0
1616
 
1617
first_string:
1618
        word    'D','H','R','Y','S','T','O','N','E',' '
1619
        word    'P','R','O','G','R','A','M',','
1620
        word    ' ','1','\'','S','T'
1621
        word    ' ','S','T','R','I','N','G'
1622
        word    0
1623
 
1624
second_string:
1625
        word    'D','H','R','Y','S','T','O','N','E',' '
1626
        word    'P','R','O','G','R','A','M',',',' '
1627
        word    '2','\'','N','D',' ','S','T','R','I','N','G'
1628
        word    0
1629
 
1630
third_string:
1631
        word    'D','H','R','Y','S','T','O','N','E',' '
1632
        word    'P','R','O','G','R','A','M',',',' '
1633
        word    '3','\'','R','D',' ','S','T','R','I','N','G'
1634
        word    0
1635
 
1636
// Arr_1_Dim    gbl_arr_1;
1637
// Arr_2_Dim    gbl_arr_2;
1638
// char gbl_ch, gbl_ch_2;
1639
// bool gbl_bool;
1640
// int  gbl_int;
1641
// RECP gbl_ptr;
1642
 
1643 69 dgisselq
;

powered by: WebSVN 2.1.0

© copyright 1999-2021 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.