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

Subversion Repositories zipcpu

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

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

powered by: WebSVN 2.1.0

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