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

Subversion Repositories zipcpu

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

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

powered by: WebSVN 2.1.0

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