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

Subversion Repositories zipcpu

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

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

powered by: WebSVN 2.1.0

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