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

Subversion Repositories zipcpu

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

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 202 dgisselq
        STO     R2,(R0)
256 69 dgisselq
        CMP     0,R2
257 202 dgisselq
        STO.NZ  R3,1(R0)
258 69 dgisselq
        CMP.NZ  0,R3
259 202 dgisselq
        STO.NZ  R4,2(R0)
260 69 dgisselq
        CMP.NZ  0,R4
261 74 dgisselq
        STO.NZ  R5,3(R0)
262 69 dgisselq
 
263
        LOD     (SP),R2
264
        LOD     1(SP),R3
265
        LOD     2(SP),R4
266
        LOD     3(SP),R5
267
        ADD     4,SP
268 74 dgisselq
#ifndef SKIP_SHORT_CIRCUITS
269
        CMP     LOAD_ADDRESS,R2
270
        HALT.LT
271
#endif
272 69 dgisselq
        JMP     R2
273
 
274
#else
275
lcl_strcpy:
276
        ; R0 = d
277
        ; R1 = s
278
        ; R3 = ch
279 57 dgisselq
copy_next_char:
280 69 dgisselq
        SUB     1,SP
281
        STO     R2,(SP)
282 41 dgisselq
#ifdef  NO_LOOP_UNROLLING
283
        LOD     (R1),R2
284
        STO     R2,(R0)
285 57 dgisselq
        CMP     0,R2
286 69 dgisselq
        BZ      lcl_strcpy_end_of_loop
287 41 dgisselq
        ADD     1,R0
288
        ADD     1,R1
289 57 dgisselq
        BRA     copy_next_char
290
 
291 41 dgisselq
#else
292
        LOD     (R1),R2
293 57 dgisselq
        STO     R2,(R0)
294 41 dgisselq
        CMP     0,R2
295 69 dgisselq
        BZ      lcl_strcpy_end_of_loop
296 41 dgisselq
        LOD     1(R1),R2
297 57 dgisselq
        STO     R2,1(R0)
298 41 dgisselq
        CMP     0,R2
299 69 dgisselq
        BZ      lcl_strcpy_end_of_loop
300 41 dgisselq
        LOD     2(R1),R2
301 57 dgisselq
        STO     R2,2(R0)
302 41 dgisselq
        CMP     0,R2
303 69 dgisselq
        BZ      lcl_strcpy_end_of_loop
304 41 dgisselq
        LOD     3(R1),R2
305 57 dgisselq
        STO     R2,3(R0)
306 41 dgisselq
        CMP     0,R2
307 69 dgisselq
        BZ      lcl_strcpy_end_of_loop
308 41 dgisselq
        ADD     4,R0
309
        ADD     4,R1
310 57 dgisselq
        BRA     copy_next_char
311 41 dgisselq
#endif
312 69 dgisselq
lcl_strcpy_end_of_loop:
313
        LOD     (SP),R2
314
        ADD     1,SP
315 74 dgisselq
#ifndef SKIP_SHORT_CIRCUITS
316
        CMP     LOAD_ADDRESS,R2
317
        BUSY.LT
318
#endif
319 69 dgisselq
        JMP     R2
320
#endif
321 41 dgisselq
 
322
//int   lcl_strcmp(char *s1, char *s2) {
323
//      char    a, b;
324
//      do {
325
//              a = *s1++; b = *s2++;
326
//      } while((a)&&(a==b));
327
//
328
//      return a-b;
329
//}
330
 
331 69 dgisselq
#ifdef  PIPELINED_STRCMP
332 41 dgisselq
lcl_strcmp:
333 69 dgisselq
        SUB     8,SP
334
        STO     R2,(SP)
335 41 dgisselq
        STO     R3,1(SP)
336 69 dgisselq
        STO     R4,2(SP)
337
        STO     R5,3(SP)
338
        STO     R6,4(SP)
339
        STO     R7,5(SP)
340
        STO     R8,6(SP)
341
        STO     R9,7(SP)
342 41 dgisselq
 
343
strcmp_top_of_loop:
344 69 dgisselq
        LOD     (R0),R2
345
        LOD     1(R0),R3
346
        LOD     2(R0),R4
347
        LOD     3(R0),R5
348
        ;
349
        LOD     (R1),R6
350
        LOD     1(R1),R7
351
        LOD     2(R1),R8
352
        LOD     3(R1),R9
353
        ;
354 74 dgisselq
        ;
355 69 dgisselq
        CMP     0,R2
356
        CMP.NZ  0,R3
357
        CMP.NZ  0,R4
358
        CMP.NZ  0,R5
359
        BZ      strcmp_end_loop
360
 
361
        CMP     R2,R6
362
        CMP.Z   R3,R7
363
        CMP.Z   R4,R8
364
        CMP.Z   R5,R9
365
        BNZ     strcmp_end_loop
366
 
367
        ADD     4,R0
368
        ADD     4,R1
369
        BRA     strcmp_top_of_loop
370
 
371
strcmp_end_loop:
372
        CMP     0,R2
373
        BZ      final_str_compare
374
        CMP     R2,R6
375
        BNZ     final_str_compare
376
 
377
        MOV     R3,R2
378
        MOV     R7,R6
379
        CMP     0,R2
380
        BZ      final_str_compare
381
        CMP     R2,R6
382
        BNZ     final_str_compare
383
 
384
        MOV     R4,R2
385
        MOV     R8,R6
386
        CMP     0,R2
387
        BZ      final_str_compare
388
        CMP     R2,R6
389
        BNZ     final_str_compare
390
 
391
        MOV     R5,R2
392
        MOV     R9,R6
393
 
394
final_str_compare:
395
        SUB     R6,R2
396
        MOV     R2,R0
397
 
398
        LOD     (SP),R2
399
        LOD     1(SP),R3
400
        LOD     2(SP),R4
401
        LOD     3(SP),R5
402
        LOD     4(SP),R6
403
        LOD     5(SP),R7
404
        LOD     6(SP),R8
405
        LOD     7(SP),R9
406
        ADD     8,SP
407 74 dgisselq
#ifndef SKIP_SHORT_CIRCUITS
408
        CMP     LOAD_ADDRESS,R2
409
        BUSY.LT
410
#endif
411 69 dgisselq
        JMP     R2
412
 
413
#else
414
lcl_strcmp:
415
        SUB     2,SP
416
        STO     R2,(SP)
417
        STO     R3,1(SP)
418
 
419
strcmp_top_of_loop:
420 41 dgisselq
#ifdef  NO_LOOP_UNROLLING
421 57 dgisselq
        ; LOD   (R0),R2
422
        ; LOD   (R1),R3                 ; Alternate approach:
423 41 dgisselq
        ; CMP   R2,R3                   ;       CMP     0,R2
424
        ; BNZ   strcmp_end_loop         ;       BZ      strcmp_end_loop
425
        ; CMP   0,R2                    ;       CMP     R2,R3
426
        ; BZ    strcmp_end_loop         ;       BZ      strcmp_top_of_loop
427
        ; CMP   0,R3                    ;
428
        ; BZ    strcmp_end_loop         ;
429
        ; ADD   1,R0
430
        ; ADD   1,R1
431
        ; BRA   strcmp_top_of_loop
432
        LOD     (R0),R2
433
        LOD     (R1),R3
434
        CMP     0,R2
435
        BZ      strcmp_end_loop
436 57 dgisselq
        ADD     1,R0
437
        ADD     1,R1
438 41 dgisselq
        CMP     R2,R3
439
        BZ      strcmp_top_of_loop
440
#else
441
        LOD     (R0),R2
442
        LOD     (R1),R3
443
        CMP     0,R2
444
        BZ      strcmp_end_loop
445
        CMP     R2,R3
446
        BNZ     strcmp_end_loop
447
        LOD     1(R0),R2
448
        LOD     1(R1),R3
449
        CMP     0,R2
450
        BZ      strcmp_end_loop
451
        CMP     R2,R3
452
        BNZ     strcmp_end_loop
453
        LOD     2(R0),R2
454
        LOD     2(R1),R3
455
        CMP     0,R2
456
        BZ      strcmp_end_loop
457
        CMP     R2,R3
458
        BNZ     strcmp_end_loop
459
        LOD     3(R0),R2
460
        LOD     3(R1),R3
461
        CMP     0,R2
462
        BZ      strcmp_end_loop
463
        CMP     R2,R3
464
        BNZ     strcmp_end_loop
465
        ADD     4,R0
466
        ADD     4,R1
467
        BRA     strcmp_top_of_loop
468
#endif
469
 
470
strcmp_end_loop:
471
        SUB     R3,R2
472
        MOV     R2,R0
473
 
474 69 dgisselq
        LOD     (SP),R2
475 41 dgisselq
        LOD     1(SP),R3
476 69 dgisselq
        ADD     2,SP
477 74 dgisselq
#ifndef SKIP_SHORT_CIRCUITS
478
        CMP     LOAD_ADDRESS,R2
479
        BUSY.LT
480
#endif
481 69 dgisselq
        JMP     R2
482
#endif
483 41 dgisselq
 
484
 
485
//test_enum     func_1(char ch_1, char ch_2) {
486
//      char    lcl_ch_1, lcl_ch_2;
487
//
488
//      lcl_ch_1 = ch_1;
489
//      lcl_ch_2 = lcl_ch_1;
490
//      if (lcl_ch_2 != ch_2)
491
//              return 0;
492
//      else {
493
//              gbl_ch = lcl_ch_1;
494
//              return 1;
495
//      }
496
 
497
#ifdef  NO_INLINE
498
func_1:
499
        ; On input,
500
        ; R0 = ch_1
501
        ; R1 = ch_2
502
        ; R2 = available
503
        ; On output, R0 is our return value
504
 
505 69 dgisselq
        SUB     1,SP
506
        STO     R2,(SP)
507 41 dgisselq
        MOV     R0,R2
508
        CMP     R2,R1
509
        CLR.NZ  R0
510
        STO.Z   R2,gbl_ch(R12)
511
        LDILO.Z 1,R0
512 69 dgisselq
        LOD     (SP),R2
513
        ADD     1,SP
514 74 dgisselq
#ifndef SKIP_SHORT_CIRCUITS
515
        CMP     LOAD_ADDRESS,R2
516
        BUSY.LT
517
#endif
518 69 dgisselq
        JMP     R2
519 41 dgisselq
#endif
520
 
521
//bool  func_2(char *str_1, char *str_2) {
522
//      int     lcl_int;
523
//      char    lcl_ch;
524
//
525
//      lcl_int = 2;
526
//      while(lcl_int <= 2) {
527
//              if (func_1(str_1[lcl_int], str_2[lcl_int+1])==0) {
528
//                      lcl_ch = 'A';
529
//                      lcl_int ++;
530
//              }
531
//      }
532
//
533
//      if ((lcl_ch >= 'W')&&(lcl_ch < 'Z'))
534
//              lcl_int = 7;
535
//      if (lcl_ch == 'R')
536
//              return true;
537
//      else {
538
//              if (lcl_strcmp(str_1, str_2)>0) {
539
//                      lcl_int += 7;
540
//                      gbl_int = lcl_int;
541
//              } else
542
//                      return false;
543
//      }
544
//}
545
func_2:
546
        ;
547
        SUB     6,SP
548 74 dgisselq
#ifndef SKIP_SHORT_CIRCUITS
549
        CMP     LOAD_ADDRESS,R2
550
        BUSY.LT
551
#endif
552
        STO     R2,(SP)         ; SP = 0x08daf
553 69 dgisselq
        STO     R3,1(SP)
554
        STO     R4,2(SP)
555
        STO     R5,3(SP)
556
        STO     R6,4(SP)
557
        STO     R7,5(SP)
558 41 dgisselq
 
559
        MOV     R0,R3   ; R3 = str_1
560
        MOV     R1,R4   ; R4 = str_2
561
        LDI     2,R5    ; R5 = lcl_int
562
        LDI     'A',R7  ; R7 = lcl_ch
563
func_2_while_loop:
564
        CMP     2,R5
565
        BGT     func_2_end_while_loop
566
func_2_top_while_loop:
567
        MOV     R3,R6
568
        ADD     R5,R6
569
 
570
#ifdef  NO_INLINE
571
        LOD     (R6),R0
572
        MOV     R4,R6
573
        ADD     R5,R6
574
        LOD     1(R6),R1
575
 
576 69 dgisselq
        MOV     __HERE__+2(PC),R2
577 41 dgisselq
        BRA     func_1
578
 
579
        CMP     0,R0
580
        ADD.Z   1,R5
581 57 dgisselq
#ifndef SKIP_SHORT_CIRCUITS
582
        BUSY.NZ
583
#endif
584 41 dgisselq
#else
585
        LOD     (R6),R2
586
        MOV     R4,R6
587
        ADD     R5,R6
588
        LOD     1(R6),R1
589
 
590
        CMP     R2,R1
591
        STO.Z   R2,gbl_ch(R12)
592
        LDILO.Z 1,R0
593
 
594
        ADD.NZ  1,R5
595 57 dgisselq
#ifndef SKIP_SHORT_CIRCUITS
596
        BUSY.Z
597 41 dgisselq
#endif
598 57 dgisselq
#endif
599 41 dgisselq
 
600
        CMP     3,R5
601
#ifndef SKIP_SHORT_CIRCUITS
602
        BUSY.LT
603
#endif
604
        BLT     func_2_top_while_loop
605
 
606
func_2_end_while_loop:
607
 
608
        // CMP  'W',R7                  // BUT! We know lcl_ch='A'
609
        // BLT  skip_if                 // So we can skip this
610
        // CMP  'Z',R7                  // entire  section
611
        // LDI.LT       7,R5
612
        // CMP  'R',R7
613
        // BNZ alt_if_case
614
        // LLO.Z        1,R0
615
        // BRA  func_2_return_and_cleanup
616
        //
617
        MOV     R3,R0
618
        MOV     R4,R1
619 69 dgisselq
        MOV     __HERE__+2(PC),R2
620 41 dgisselq
        BRA     lcl_strcmp
621
        CMP     0,R0
622
        BGT     func_2_final_then
623
        CLR     R0
624
        BRA     func_2_return_and_cleanup
625
func_2_final_then:
626
        // ADD  7,R5            ; Never read, so useless code
627
        LDI     1,R0
628
#ifndef SKIP_SHORT_CIRCUITS
629
        BUSY
630
#endif
631
func_2_return_and_cleanup:
632
 
633 69 dgisselq
        LOD     (SP),R2
634
        LOD     1(SP),R3
635
        LOD     2(SP),R4
636
        LOD     3(SP),R5
637
        LOD     4(SP),R6
638
        LOD     5(SP),R7
639 41 dgisselq
        ADD     6,SP
640 74 dgisselq
#ifndef SKIP_SHORT_CIRCUITS
641
        CMP     LOAD_ADDRESS,R2
642
        BUSY.LT
643
#endif
644 69 dgisselq
        JMP     R2
645 41 dgisselq
 
646
//bool  func_3(test_enum a) {
647
//      test_enum       lcl_enum;
648
//
649
//      lcl_enum = a;
650
//      if (lcl_enum == Ident_3)
651
//              return true;
652
//      else
653
//              return false;
654
//}
655
 
656
#ifdef  NO_INLINE
657
func_3:
658
        ; On entry,
659
        ;  R0 = a
660
        ;  R1 - available
661
        CMP     2,R0
662 69 dgisselq
        CLR     R0      ; CLR Doesn't set flags
663
        LDILO.Z 1,R0
664 74 dgisselq
#ifndef SKIP_SHORT_CIRCUITS
665
        CMP     LOAD_ADDRESS,R1
666
        BUSY.LT
667
#endif
668 69 dgisselq
        JMP     R1
669 41 dgisselq
#endif
670
 
671
 
672
// void proc_6(test_enum ev, test_enum *ep) {
673
//      *ep = ev;
674
//      if (!func_3(ev))
675
//              *ep = 3;
676
//      switch(ev) {
677
//              case 0: *ep = 0; break;
678
//              case 1:
679
//                      if (gbl_int > 100)
680
//                              *ep = 0;
681
//                      else
682
//                              *ep = 3;
683
//                      break;
684
//              case 2:
685
//                      *ep = 1;
686
//                      break;
687
//              case 3:
688
//                      break;
689
//              case 4:
690
//                      *ep = 2;
691
//      }
692
//}
693
 
694
proc_6:
695
        ; On entry:
696
        ;       R0 = ev
697
        ;       R1 = ep
698 69 dgisselq
        ;       R2 = link address
699 41 dgisselq
        ; Since we call func_3, we have to reserve R0 and R1
700
        ; for other purposes.  Thus
701
        ;       R2 = ev
702
        ;       R3 = ep
703
        SUB     2,SP
704 69 dgisselq
        STO     R2,(SP)
705
        STO     R3,1(SP)
706 41 dgisselq
 
707
        MOV     R1,R3
708
        MOV     R0,R2
709
        ; *ep = ev
710
        STO     R0,(R1)
711
#ifndef SKIP_SHORT_CIRCUITS
712
        CMP     2,R0
713
        BUSY.NZ
714
#endif
715
 
716
#ifdef  NO_INLINE
717
        ; !func_3(ev)
718 69 dgisselq
        MOV     __HERE__+2(PC),R1
719 41 dgisselq
        BRA     func_3
720
 
721
        TST     -1,R0
722
        LDI     3,R1
723 69 dgisselq
#ifndef SKIP_SHORT_CIRCUITS
724
        BUSY.Z
725
#endif
726 41 dgisselq
        STO.Z   R1,(R3)
727
#else
728 69 dgisselq
        CMP     2,R0
729 41 dgisselq
        LDI     3,R1
730 74 dgisselq
#ifndef SKIP_SHORT_CIRCUITS
731 69 dgisselq
        BUSY.NZ
732 41 dgisselq
#endif
733 69 dgisselq
        STO.NZ  R1,(R3)
734 41 dgisselq
#endif
735
 
736
#ifndef SKIP_SHORT_CIRCUITS
737
        CMP     2,R2
738
        BUSY.NZ
739
#endif
740
        CMP     0,R2
741
        BNZ     proc_6_case_not_zero
742
#ifndef SKIP_SHORT_CIRCUITS
743
        BUSY
744
#endif
745
        LDI     0,R1
746
        STO     R1,(R3)
747
        BRA     proc_6_end_of_case
748
proc_6_case_not_zero:
749
        CMP     1,R2
750
        BNZ     proc_6_case_not_one
751
#ifndef SKIP_SHORT_CIRCUITS
752
        BUSY
753
#endif
754
        LDI     3,R0
755
        LOD     gbl_int(R12),R1
756
        CMP     100,R1
757
        CLR.GT  R0
758
        STO     R0,(R3)
759
        BRA     proc_6_end_of_case
760
proc_6_case_not_one:
761
        CMP     2,R2
762
        BNZ     proc_6_case_not_two
763
        LDI     1,R1                            // Executed, if done properly
764
        STO     R1,(R3)
765
        BRA     proc_6_end_of_case
766
proc_6_case_not_two:
767
#ifndef SKIP_SHORT_CIRCUITS
768 74 dgisselq
        NOOP                            ;;;;;;;; TODO This fails--needs the NOOP
769
        BUSY                            ;;;;;;;; TODO so as not to do the BUSY
770 41 dgisselq
#endif
771
        CMP     4,R2
772
        BNZ     proc_6_case_not_four
773
        LDI     2,R1
774
        STO     R1,(R3)
775
        // BRA  proc_6_end_of_case
776
proc_6_case_not_four:
777
proc_6_end_of_case:
778 69 dgisselq
        LOD     (SP),R2
779
        LOD     1(SP),R3
780 74 dgisselq
#ifndef SKIP_SHORT_CIRCUITS
781
        CMP     LOAD_ADDRESS,R2         ; TODO This fails, even when the address
782
        BUSY.LT
783
#endif
784 41 dgisselq
        ADD     2,SP
785 69 dgisselq
        JMP     R2
786 41 dgisselq
 
787
// void proc_7(int a, int b, int *c) {
788
//      int     lcl;
789
//
790
//      lcl = a + 2;
791
//      *c = b + a;
792
//}
793
 
794
#ifdef  NO_INLINE
795
proc_7:
796
        ADD 2+R0,R1
797
        STO R1,(R2)
798
 
799 74 dgisselq
#ifndef SKIP_SHORT_CIRCUITS
800
        CMP     LOAD_ADDRESS,R3
801
        BUSY.LT
802
#endif
803 69 dgisselq
        JMP     R3
804 41 dgisselq
#endif
805
 
806
//      int     a[50];
807
//      int     b[50][50];
808
//
809
// void proc_8(Arr_1_Dim a, Arr_2_Dim b, int c, int d) {
810
//      int     idx, loc;
811
//
812
//      loc = c+5;
813
//      a[loc] = d;
814
//      a[loc+1] = a[loc];
815
//      a[loc+30] = loc;
816
//      for(idx=loc; idx<= loc+1; idx++)
817
//              b[loc][idx] = loc;
818
//      b[loc][loc-1] += 1;
819
//      b[loc+20][loc] = a[loc];
820
//      gbl_int = 5;
821
//}
822
proc_8:
823
        ; R0 = a
824
        ; R1 = b
825
        ; R2 = c
826
        ; R3 = d
827
        ; R4 - unassigned
828
        ; Makes no function/procedure calls, so these can keep
829
        ; R2 = loc = c+5, replaces c
830
        ; R4 = idx
831 69 dgisselq
        SUB     3,SP
832
        STO     R4,(SP)
833 41 dgisselq
        STO     R5,1(SP)
834
        STO     R6,2(SP)
835
 
836
        ADD     5,R2    ; loc = c+5
837
        MOV     R0,R5
838
        ADD     R2,R5
839
        STO     R3,(R5)
840
        STO     R3,1(R5)
841
        STO     R2,30(R5)
842
        MOV     R2,R5
843 152 dgisselq
        MPY     50,R5   ; R5 = 50 * R2 = 50 * loc
844 41 dgisselq
        ADD     R1,R5   ; R5 = &b[loc][0]
845
        MOV     R5,R6   ; R6 = &b[loc][0]
846
        ADD     R2,R5   ; R5 = &b[loc][loc]
847
        MOV     R2,R4   ; R4 = loc = index
848
proc_8_top_of_loop:
849
        CMP     1(R2),R4
850
        BGT     proc_8_end_of_loop
851
proc_8_loop_after_condition:
852
        STO     R2,(R5)
853
        ADD     1,R5
854
        ADD     1,R4
855
        CMP     2(R2),R4
856
        BLT     proc_8_loop_after_condition
857
proc_8_end_of_loop:
858
 
859
        ; b[loc][loc-1] += 1
860
        ADD     R2,R6           ; R6 = &b[loc][loc]
861
        LOD     -1(R6),R5
862
        ADD     1,R5
863
        STO     R5,-1(R6)
864
        ; b[loc+20][loc] = a[loc]
865
        MOV     R0,R4
866
        ADD     R2,R4
867
        LOD     (R4),R3
868
        STO     R3,20*50(R6)
869
        LDI     5,R3
870
        STO     R3,gbl_int(R12)
871
 
872 69 dgisselq
        LOD     (SP),R4
873 41 dgisselq
        LOD     1(SP),R5
874
        LOD     2(SP),R6
875 69 dgisselq
        ADD     3,SP
876 74 dgisselq
#ifndef SKIP_SHORT_CIRCUITS
877
        CMP     LOAD_ADDRESS,R4
878
        BUSY.LT
879
#endif
880 69 dgisselq
        JMP     R4
881 41 dgisselq
 
882
// void proc_5(void) {
883
//      gbl_ch = 'A';
884
//      gbl_bool = false;
885
//}
886
#ifdef  NO_INLINE
887
proc_5:
888 69 dgisselq
        SUB     1,SP
889
        STO     R0,(SP)
890
        ;
891 41 dgisselq
        LDI     'A',R0
892
        STO     R0,gbl_ch(R12)
893
        CLR     R0
894
        STO     R0,gbl_bool(R12)
895
        ;
896 69 dgisselq
        LOD     (SP),R0
897
        ADD     1,SP
898
        JMP     R0
899 41 dgisselq
#endif
900
 
901
// void proc_4(void) {
902
//      bool    lcl_bool;
903
//      lcl_bool = (gbl_ch == 'A');
904
//      gbl_ch_2 = 'B';
905
// }
906
#ifdef  NO_INLINE
907
proc_4:
908
        //
909
        ; LDI   GBL,R12 // Already in R12
910
        ; Setting lcl_bool is irrelevant, so the optimizer should remove it.
911
        ; R0 doesn't need to be saved, since it's already trashed by the
912
        ; subroutine call.
913
        ;
914
        ; LOD   gbl_ch(R12),R0
915
        ; CLR   R1
916
        ; CMP   'A',R0
917
        ; ADD.Z 1,R1
918
        ;
919 69 dgisselq
        SUB     1,SP
920
        STO     R0,(SP)
921
        ;
922 41 dgisselq
        LDI     'B',R0
923
        STO     R0,gbl_ch_2(R12)
924
        ;
925 69 dgisselq
        LOD     (SP),R0
926
        ADD     1,SP
927
        JMP     R0
928 41 dgisselq
#endif
929
 
930
// void proc_3(RECP *a) {
931
//      if (gbl_ptr != NULL)
932
//              *a = gbl_ptr->ptr_comp;
933
//      proc_7(10,gbl_int, &gbl_ptr->variant.var_1.int_comp); // ??
934
//}
935
proc_3:
936
        SUB     3,SP
937 69 dgisselq
        STO     R1,(SP)
938
        STO     R2,1(SP)
939 41 dgisselq
        STO     R3,2(SP)
940
        ;
941
        LOD     gbl_ptr(R12),R2
942
        TST     -1,R2
943
#ifndef SKIP_SHORT_CIRCUITS
944
        BUSY.Z
945
#endif
946
        LOD.NZ  ptr_comp(R2),R3
947
        STO.NZ  R3,(R0)
948
#ifdef  NO_INLINE
949
        LDI     10,R0
950
        LOD     gbl_int(R12),R1
951
        MOV     variant.var_1.int_comp(R2),R2
952 69 dgisselq
        MOV     __HERE__+2(PC),R3
953 41 dgisselq
        BRA     proc_7
954
#else
955
        LOD     gbl_int(R12),R1
956
        ADD      12,R1
957
        STO      R1,variant.var_1.int_comp(R2)
958
#endif
959
        ;
960 69 dgisselq
        LOD     (SP),R1
961
        LOD     1(SP),R2
962 41 dgisselq
        LOD     2(SP),R3
963
        ADD     3,SP
964 74 dgisselq
#ifndef SKIP_SHORT_CIRCUITS
965
        CMP     LOAD_ADDRESS,R1
966
        BUSY.LT
967
#endif
968 69 dgisselq
        JMP     R1
969 41 dgisselq
 
970
// void proc_2(int *a) {
971
//      int             lcl_int;
972
//      test_enum       lcl_enum;
973
//
974
//      lcl_int = *a + 10;
975
//      do {
976
//              if (gbl_ch == 'A') {
977
//                      lcl_int -= 1;
978
//                      *a = lcl_int - gbl_int;
979
//                      lcl_enum = Ident_1;
980
//              }
981
//      } while(lcl_enum != Ident_1);
982
//}
983
proc_2:
984 69 dgisselq
        SUB     6,SP
985
        STO     R1,(SP)
986
        STO     R2,1(SP)
987
        STO     R3,2(SP)
988 41 dgisselq
        STO     R4,3(SP)
989 69 dgisselq
        STO     R5,4(SP)
990
        STO     R6,5(SP)
991 41 dgisselq
        // R1 doesn't need to be stored, it was used in the subroutine
992
        // call calculation
993
 
994
        LOD     (R0),R1
995
        MOV     10(R1),R2       ; R2 = lcl_int
996
        LOD     gbl_ch(R12),R4  ; R4 = gbl_ch
997
#ifdef  NO_CHEATING
998
proc_2_loop:
999
        CMP     'A',R4
1000
        SUB.Z   1,R2
1001
        LOD.Z   gbl_int(R12),R5 ; R5 = gbl_int
1002
        MOV.Z   R2,R6           ; R6 = lcl_int
1003
        SUB.Z   R5,R6           ; lcl_int - gbl_int
1004
        STO.Z   R6,(R0)         ; *a = R6
1005
        CLR.Z   R3              ; lcl_enum = 0
1006
// #ifndef      SKIP_SHORT_CIRCUITS
1007
        // BUSY.NZ
1008
// #endif
1009
 
1010
        TST     -1,R3
1011
// #ifndef      SKIP_SHORT_CIRCUITS
1012
        // BUSY.NZ
1013
// #endif
1014
        BNZ     proc_2_loop
1015
#else
1016
        LOD     gbl_int(R12),R5
1017
        SUB     1(R5),R2
1018
        STO     R2,(R0)
1019
#endif
1020
        ;
1021 69 dgisselq
        LOD     (SP),R1
1022
        LOD     1(SP),R2
1023
        LOD     2(SP),R3
1024 41 dgisselq
        LOD     3(SP),R4
1025 69 dgisselq
        LOD     4(SP),R5
1026
        LOD     5(SP),R6
1027
        ADD     6,SP
1028 74 dgisselq
#ifndef SKIP_SHORT_CIRCUITS
1029
        CMP     LOAD_ADDRESS,R1
1030
        BUSY.LT
1031
#endif
1032 69 dgisselq
        JMP     R1
1033 41 dgisselq
 
1034
//void  proc_1 (RECP a) {
1035
//      RECP    nxt = a->ptr_comp;
1036
//
1037
//      // structassign(a->ptr_comp, gbl_ptr);
1038
//      *(a->ptr_comp) = *(gbl_ptr);
1039
//
1040
//      a->variant.var_1.int_comp = 5;
1041
//      nxt->variant.var_1.int_comp = a->variant.var_1.int_comp;
1042
//      proc_3(&nxt->ptr_comp);
1043
//
1044
//      if (nxt->discr == 0) {
1045
//              nxt->variant.var_1.int_comp = 6;
1046
//              proc_6(a->variant.var_1.enum_comp, &nxt->variant.var_1.enum_comp);
1047
//              nxt->ptr_comp = gbl_ptr->ptr_comp;
1048
//              proc_7(nxt->variant.var_1.int_comp, 10, &nxt->variant.var_1.int_comp);
1049
//      } else
1050
//              // structassign(a, a->ptr_comp);
1051
//              *a = *(a->ptr_comp);
1052
//}
1053
proc_1:
1054 69 dgisselq
        SUB     11,SP
1055
        STO     R1,(SP)
1056
        STO     R2,1(SP)
1057
        STO     R3,2(SP)
1058
        STO     R4,3(SP)
1059
        STO     R5,4(SP)
1060
        STO     R6,5(SP)
1061
        STO     R7,6(SP)
1062
        STO     R8,7(SP)
1063
        STO     R9,8(SP)
1064
#ifndef NO_LOOP_UNROLLING
1065
        STO     R10,9(SP)
1066
        STO     R11,10(SP)
1067
#endif
1068 41 dgisselq
 
1069
        ; R9 = a
1070
        ; R4 = nxt
1071
        ; R12 = GBL
1072
        ; R13 = SP
1073
        MOV     R0,R9
1074
        LOD     ptr_comp(R9),R4
1075
#ifndef SKIP_SHORT_CIRCUITS
1076 74 dgisselq
        TST     -1,R4           ; R4 = 0x100e9f
1077 41 dgisselq
        BUSY.Z
1078 74 dgisselq
        CMP     PC,R9           ; R9 = 0x100ec2
1079 69 dgisselq
        BUSY.LT
1080 41 dgisselq
#endif
1081
        MOV     R9,R6
1082 74 dgisselq
        LOD     gbl_ptr(R12),R7 ; (0x100a04) -> 0x100ec2
1083
        ; BUSY                  ; R7 = 0x0100ec2
1084 69 dgisselq
 
1085
#ifndef SKIP_SHORT_CIRCUITS
1086
        LOD     variant.var_1.enum_comp(R7), R0
1087 74 dgisselq
        CMP     2,R0            ; R0 = 0
1088
        BUSY.NZ                 ; TODO Fails here
1089 69 dgisselq
#endif
1090
 
1091
#ifdef  NO_LOOP_UNROLLING
1092
        LDI     35,R5
1093 41 dgisselq
proc_1_assign_loop_1:
1094
        LOD     (R6),R8
1095
        ADD     1,R6
1096
        STO     R8,(R7)
1097
        ADD     1,R7
1098
        SUB     1,R5
1099
        BNZ     proc_1_assign_loop_1;
1100 69 dgisselq
#else
1101 41 dgisselq
 
1102 69 dgisselq
        ; R2 is available
1103
        ; R3 is available
1104
 
1105
        LDI     34,R5
1106
proc_1_assign_loop_1:
1107
        LOD     (R6),R8
1108
        LOD     1(R6),R10
1109
        LOD     2(R6),R11
1110
        LOD     3(R6),R2
1111
        LOD     4(R6),R3
1112
        ADD     5,R6
1113
        SUB     5,R5
1114
        STO     R8,(R7)
1115
        STO     R10,1(R7)
1116
        STO     R11,2(R7)
1117
        STO     R2,3(R7)
1118
        STO     R3,4(R7)
1119
        BLT     proc_1_assign_loop_1_end
1120
        ADD     5,R7
1121
        ; BNZ   proc_1_assign_loop_1;
1122
        BRA     proc_1_assign_loop_1
1123
proc_1_assign_loop_1_end:
1124
        ; Loop length is fixed, nothing to test here
1125
#endif
1126
 
1127 41 dgisselq
#ifndef SKIP_SHORT_CIRCUITS
1128
        LOD     gbl_ptr(R12),R2
1129
        TST     -1,R2
1130
        BUSY.Z
1131 69 dgisselq
        ;
1132
        LOD     variant.var_1.enum_comp(R9), R0
1133
        CMP     2,R0
1134
        BUSY.NZ
1135 41 dgisselq
#endif
1136
 
1137
        LDI     5,R5
1138
        STO     R5,variant.var_1.int_comp(R9)
1139
        STO     R5,variant.var_1.int_comp(R4)
1140 74 dgisselq
        MOV     ptr_comp(R4),R0                 ; R4 = 0x8e41, ptr_comp(R4)=R4
1141 69 dgisselq
        MOV     __HERE__+2(PC),R1
1142 41 dgisselq
        BRA     proc_3          ; Uses R0 and R1
1143
 
1144
        LOD     discr(R4),R5
1145
        CMP     0,R5
1146
        BNZ     proc_1_last_struct_assign
1147
        ; This is the juncture that is "supposed" to be taken
1148
        LDI     6,R5
1149
 
1150
        STO     R5,variant.var_1.int_comp(R4)
1151
        LOD     variant.var_1.enum_comp(R9), R0
1152
#ifndef SKIP_SHORT_CIRCUITS
1153
        CMP     2,R0
1154
        BUSY.NZ
1155
#endif
1156
        MOV     variant.var_1.enum_comp+R4, R1
1157 69 dgisselq
        MOV     __HERE__+2(PC),R2
1158 41 dgisselq
        BRA     proc_6
1159
        ;
1160
        LOD     gbl_ptr(R12),R5
1161 74 dgisselq
        LOD     ptr_comp(R5),R5
1162 41 dgisselq
        STO     R5,ptr_comp(R4)
1163
        ;
1164
#ifdef  NO_INLINE
1165
        LOD     variant.var_1.int_comp(R4),R0
1166
        LDI     10,R1
1167
        MOV     variant.var_1.int_comp(R4),R2
1168
        MOV     proc_1_return_closeout(PC),R3
1169
        BRA     proc_7
1170
#else
1171
        LOD     variant.var_1.int_comp(R4),R0
1172
        ADD     12,R0
1173
        STO     R0,variant.var_1.int_comp(R4)
1174
        BRA     proc_1_return_closeout
1175
#endif
1176
        ;
1177
proc_1_last_struct_assign:
1178
#ifndef SKIP_SHORT_CIRCUITS
1179
        BUSY
1180
#endif
1181
        LDI     35,R4
1182
        MOV     R2,R5
1183
        LOD     gbl_ptr(R12),R6
1184
proc_1_assign_loop_2:
1185
        LOD     (R6),R8
1186
        STO     R8,(R7)
1187
        ADD     1,R6
1188
        ADD     1,R7
1189
        SUB     1,R5
1190
        BNZ     proc_1_assign_loop_2
1191
        //
1192
proc_1_return_closeout:
1193
        //
1194 69 dgisselq
        LOD     (SP),R1
1195
        LOD     1(SP),R2
1196
        LOD     2(SP),R3
1197
        LOD     3(SP),R4
1198
        LOD     4(SP),R5
1199
        LOD     5(SP),R6
1200
        LOD     6(SP),R7
1201
        LOD     7(SP),R8
1202
        LOD     8(SP),R9
1203
#ifndef NO_LOOP_UNROLLING
1204
        LOD     9(SP),R10
1205
        LOD     10(SP),R11
1206
#endif
1207
        ADD     11,SP
1208 74 dgisselq
#ifndef SKIP_SHORT_CIRCUITS
1209
        CMP     LOAD_ADDRESS,R1
1210
        BUSY.LT
1211
#endif
1212 69 dgisselq
        JMP     R1              // Jumps to wrong address ??
1213 41 dgisselq
 
1214
// void dhrystone(void) {
1215
//      int     lcl_int_1, lcl_int_2, lcl_int_3, index, number_of_runs = 500;
1216
//      test_enum       lcl_enum;
1217
//      char    lcl_str_1[30], lcl_str_2[30], ch_index;
1218
//      REC_T   a, b, *nxt = &a;
1219
//
1220
//      gbl_ptr = &b;
1221
//      gbl_ptr->ptr_comp = nxt;
1222
//      gbl_ptr->variant.var_1.enum_comp = 2;
1223
//      gbl_ptr->variant.var_1.int_comp = 40;
1224
//      lcl_strcpy(gbl_ptr->variant.var_1.str_comp, "DHRYSTONE PROGRAM, SOME STRING");
1225
//      lcl_strcpy(lcl_str_1, "DHRYSTONE PROGRAM, 1\'ST STRING");
1226
//
1227
//      gbl_arr_2[8][7] = 10;
1228
//
1229
//      for(index=0; index < number_of_runs; index++) {
1230
//              proc_5();
1231
//              proc_4();
1232
//              lcl_int_1 = 2;
1233
//              lcl_int_2 = 3;
1234
//              lcl_strcpy(lcl_str_2, "DHRYSTONE PROGRAM, 2\'ND STRING");
1235
//              lcl_enum = Ident_2;
1236
//              gbl_bool = !func_2(lcl_str_1, lcl_str_2);
1237
//              while(lcl_int_1 < lcl_int_2) {
1238
//                      lcl_int_3 = 5 * lcl_int_1 - lcl_int_2;
1239
//                      proc_7(lcl_int_1, lcl_int_2, &lcl_int_3);
1240
//                      lcl_int_1 += 1;
1241
//              }
1242
//
1243
//              proc_8(gbl_arr_1, gbl_arr_2, lcl_int_1, lcl_int_3);
1244
//              proc_1(gbl_ptr);
1245
//
1246
//              for(ch_index='A'; ch_index <= gbl_ch_2; ch_index++) {
1247
//                      if (lcl_enum == func_1(ch_index, 'C')) {
1248
//                              // Then not executed??
1249
//                              proc_6(0, &lcl_enum);
1250
//                              lcl_strcpy(lcl_str_2, "DHRYSTONE PROGRAM, 3\'RD STRING");
1251
//                              lcl_int_2 = index;
1252
//                              gbl_int = index;
1253
//                      }
1254
//              }
1255
//
1256
//              lcl_int_2 = lcl_int_2 * lcl_int_1;
1257
//              lcl_int_1 = lcl_int_2 / lcl_int_3;
1258
//              lcl_int_2 = 7 * ( lcl_int_2 - lcl_int_3) - lcl_int_1;
1259
//              proc_2(&lcl_int_1);
1260
//      }
1261
//}
1262
 
1263
dhrystone:
1264
#ifdef  SUPERVISOR_TASK
1265
        SUB     12+RECSIZE+RECSIZE+30+30+3,SP
1266
        ; Leave a space on the top of the stack for calling
1267
        ; subroutines.
1268 69 dgisselq
        STO     R0,(SP)
1269
        STO     R1,1(SP)
1270
        STO     R2,2(SP)
1271
        STO     R3,3(SP)
1272
        STO     R4,4(SP)
1273
        STO     R5,5(SP)
1274
        STO     R6,6(SP)
1275
        STO     R7,7(SP)
1276
        STO     R8,8(SP)
1277
        STO     R9,9(SP)
1278
        STO     R10,10(SP)
1279
        STO     R11,11(SP)
1280 41 dgisselq
        lcl_int_1       equ     12                      ; plus SP
1281
#else
1282
        lcl_int_1       equ     2                       ; plus SP
1283
        SUB     2+RECSIZE+RECSIZE+30+30+3,SP
1284
#endif
1285
        // 12 is the global variable pointer
1286
        // 13 is our stack
1287
        // 14 is our condition code register
1288
        // 15 is the program counter
1289
        ;
1290
        lcl_int_3       equ     lcl_int_1+1             ; plus SP
1291
        lcl_enum        equ     lcl_int_3+1             ; plus SP
1292
        lcl_str_1       equ     lcl_enum+1              ; plus SP
1293
        lcl_str_2       equ     lcl_str_1+30            ; plus SP
1294
        rec_a           equ     lcl_str_2+30            ; plus SP
1295
        rec_b           equ     rec_a+RECSIZE           ; plus SP
1296
 
1297
//      int     lcl_int_1, lcl_int_2, lcl_int_3, index, number_of_runs = 500;
1298
//      test_enum       lcl_enum;
1299
//      char    lcl_str_1[30], lcl_str_2[30], ch_index;
1300
//      REC_T   a, b, *nxt = &a;
1301
//
1302
//      gbl_ptr = &b;
1303
        MOV     rec_b(SP),R0            ; R0 = &b
1304
        STO     R0,gbl_ptr(PC)
1305
//      gbl_ptr->ptr_comp = nxt;
1306
        MOV     rec_a(SP),R1            ; R1 = &a = nxt
1307
        STO     R1,ptr_comp(R0)         ; gbp_ptr->ptr.comp=b->ptr.comp=R1=nxt
1308
//      gbl_ptr->variant.var_1.enum_comp = 2;
1309
        LDI     2,R2
1310
        STO     R2,variant.var_1.enum_comp(R0)
1311
//      gbl_ptr->variant.var_1.int_comp = 40;
1312
        LDI     40,R2
1313
        STO     R2,variant.var_1.int_comp(R0)
1314
//      lcl_strcpy(gbl_ptr->variant.var_1.str_comp, "DHRYSTONE PROGRAM, SOME STRING");
1315
        MOV     variant.var_1.str_comp(R0),R0
1316
        MOV     some_string(PC),R1
1317 69 dgisselq
        MOV     __HERE__+2(PC),R2
1318 41 dgisselq
        BRA     lcl_strcpy
1319
 
1320
//      lcl_strcpy(lcl_str_1, "DHRYSTONE PROGRAM, 1\'ST STRING");
1321
        MOV     lcl_str_1(SP),R0
1322
        MOV     first_string(PC),R1
1323 69 dgisselq
        MOV     __HERE__+2(PC),R2
1324 41 dgisselq
        BRA     lcl_strcpy
1325
 
1326
//      gbl_arr_2[8][7] = 10;
1327
        LDI     10,R0
1328
        STO     R0,8*50+7+gbl_arr_2(R12)
1329
//
1330
//      for(index=0; index < number_of_runs; index++) {
1331
        ; Let R11 be our index
1332
        CLR     R11
1333
dhrystone_main_loop:
1334
        ;; Start of Dhrystone main loop
1335
        ; proc_5();
1336
#ifdef  NO_INLINE
1337 69 dgisselq
        MOV     __HERE__+2(PC),R0
1338 41 dgisselq
        BRA     proc_5
1339
#else
1340
        LDI     'A',R0
1341
        STO     R0,gbl_ch(R12)
1342
        CLR     R0
1343
        STO     R0,gbl_bool(R12)
1344
#endif
1345
        ; proc_4();
1346
#ifdef  NO_INLINE
1347 69 dgisselq
        MOV     __HERE__+2(PC),R0
1348 41 dgisselq
        BRA     proc_4
1349
#else
1350
        LDI     'B',R0
1351
        STO     R0,gbl_ch_2(R12)
1352
#endif
1353
//              lcl_int_1 = 2;
1354
        LDI     2,R5
1355
        STO     R5,lcl_int_1(SP)
1356
//              lcl_int_2 = 3;
1357
        LDI     3,R6
1358
//              lcl_strcpy(lcl_str_2, "DHRYSTONE PROGRAM, 2\'ND STRING");
1359
        MOV     lcl_str_2(SP),R0
1360
        MOV     second_string(PC),R1
1361 69 dgisselq
        MOV     __HERE__+2(PC),R2
1362 41 dgisselq
        BRA     lcl_strcpy
1363
//              lcl_enum = Ident_2;
1364
        LDI     2,R0
1365
        STO     R0,lcl_enum(SP)
1366
//              gbl_bool = !func_2(lcl_str_1, lcl_str_2);
1367
        MOV     lcl_str_1(SP),R0
1368
        MOV     lcl_str_2(SP),R1
1369 69 dgisselq
        MOV     __HERE__+2(PC),R2
1370 41 dgisselq
        BRA     func_2
1371
        CLR     R1
1372
        TST     -1,R0
1373
        LDILO.Z 1,R1
1374
        STO     R1,gbl_bool(PC)
1375
 
1376
//              while(lcl_int_1 < lcl_int_2) {
1377
        ; R5 = lcl_int_1 = 2 on entry
1378
        ; R6 = lcl_int_2 = 3 on entry, so no entry test is required
1379
        LOD     lcl_int_1(SP),R5
1380
        // The 'while' comparison
1381
        CMP     R6,R5
1382
        BGE     dhrystone_end_while_loop
1383
dhrystone_while_loop:
1384
//                      lcl_int_3 = 5 * lcl_int_1 - lcl_int_2;
1385
        MOV     R5,R7
1386 152 dgisselq
        MPY     5,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 152 dgisselq
        MPY     R5,R6   ; lcl_int_2 =
1509 41 dgisselq
//              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 152 dgisselq
        MPY     7,R6
1529 41 dgisselq
        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.