progs: bench tools bei deepjit.s geadded
[calu.git] / progs / deepjit.s
1 #define PROGINSTR stw r0, PDATA(r13)
2 #include "dt_inc.s"
3 .data
4 .org 0x10
5 inputdata:
6 ;8 * 8 4
7 .fill 1, 0x382A3834
8 ;1 X * 8
9 .fill 1, 0x31582A38
10 ;+ D X -
11 .fill 1, 0x2B44582D
12 ;P \xF8 J D
13 .fill 1, 0x50F84A44
14 ;+ * 8 6
15 .fill 1, 0x2B2A3836
16 ;\000 \020 I D
17 .fill 1, 0x00204944
18 ;~ < \000 \000
19 .fill 1, 0x7E3C0000
20 ;8 P \005 J
21 .fill 1, 0x3850054A
22 ;* 8
23 .fill 1, 0x2A38
24
25 stack:
26 .fill 256, 0
27
28 ;needed for jumps
29 ;assuming that no more than 42 instr are used
30 instrtable:
31 .fill 42, 0
32
33 prog_eof:
34 .ifill pop r0
35 .ifill ret+
36
37 prog_mul:
38 .ifill pop r6
39 .ifill pop r7
40 .ifill ldis r8, 0;0xed400004
41 .ifill mov r0, r7;0xe1038000
42 .ifill andx r0, 1;0xe2800008
43 .ifill adddnz r8, r8, r6;0x00443001
44 .ifill subinz r7, r7, 1;0x01bb8008
45 .ifill addizs r7, r7, 0;0x113b8000
46 ;loop:
47 .ifill adddnz r8, r8, r6;0x00443001
48 .ifill adddnz r8, r8, r6;0x00443001
49 .ifill subi r7, r7, 2;0xe1bb8010
50 .fill 0x0b7ffe83;brnz+ loop
51 .ifill push r8
52
53 prog_consts:
54 .fill 0xed300004;ldis r6, CONST
55 .ifill push r6
56
57 prog_add:
58 .ifill pop r6
59 .ifill pop r7
60 .ifill add r7, r7, r6;0xe03bb000
61 .ifill push r7
62
63 prog_sub:
64 .ifill pop r6
65 .ifill pop r7
66 .ifill sub r7, r7, r6;0xe0bbb000
67 .ifill push r7
68
69 prog_lessthan:
70 .ifill pop r6
71 .ifill pop r7
72 .ifill cmp r7, r6;0xec3b0000
73 .ifill pushlt r14
74 .ifill pushge r15
75
76 prog_dup:
77 .ifill fetch r6
78 .ifill push r6
79
80 prog_jmp:
81 .ifill pop r6
82 .ifill cmpi r6,0;0xecb00000
83 ;static calced
84 .fill 1, 0x1b000103;breq- vm_next
85 .fill 1, 0xeb000003;br+ CONST
86
87 prog_imm:
88 .fill 1, 0xed400000;ldil r6, CONST
89 .fill 1, 0xed400002;ldih r6, CONST
90 .ifill push r6
91
92 prog_pop:
93 .ifill disc
94
95 prog_xch:
96 .ifill pop r6
97 .ifill pop r7
98 .ifill push r6
99 .ifill push r7
100
101 prog_not:
102 .ifill pop r6
103 .ifill not r6;0xe4b7fffa
104 .ifill push r6
105
106 .text
107 .org 0
108 start:
109         call+ main
110         call+ main
111         ret
112
113
114 main:
115
116         call+ u_init
117         call+ u_recv_byte
118
119         ; benchprolog
120         call t_init
121         call t_stop
122         ldis r1, 0
123         call t_valset
124         call t_start
125         ; /benchprolog
126
127         ;set address of input
128         ldis r1, inputdata@lo
129         ldih r1, inputdata@hi
130
131         ;set address of program start
132         ldis r2, (prog_start/4)@lo
133         ldih r2, (prog_start/4)@hi
134
135         ;set address to instruction table
136         ldis r3, instrtable@lo
137         ldih r3, instrtable@hi
138
139         ;set address to defer table
140         ldis r9, defertable@lo
141         ldih r9, defertable@hi
142
143         ldis r13, PBASE@lo
144         ldih r13, PBASE@hi
145
146         ;set programmer address
147         stw r2, PADDR(r13)
148
149         ;call jit compiler
150         call+ jit
151
152         ;set address to stack
153         ;ldil r3, stack@lo
154         ;ldih r3, stack@hi
155
156         ;make r15 a 0-register
157         ldis r15, 0
158         ;make r14 a 8-bit -1-register
159         ldis r14, 0xFF
160
161         ;call jit'ed prog
162         call+ prog_start
163
164         ; benchepilog
165         push r0
166         call+ t_init
167         call+ t_stop
168         call+ t_valget
169         subi r0, r0, 0xd ; offset abziehen
170         pop r3
171         push r0
172         push r3
173         ; /benchepilog
174
175         ;send result
176         call+ u_init
177         pop r1
178         call u_send_byte
179         call u_send_newline
180         pop r1
181         call u_send_uint
182         call u_send_newline
183
184         br+ main
185
186 ;first version only supports backward jumps
187 jit:
188         ;r1 ... address to input, every byte is a new input
189         ;       includes pc implicitly
190         ;r2 ... address to program start
191         ;r3 ... address of instruction table
192         ;r4 ... gets loaded with instr. prog. addr.
193         ;r5 ... input
194         ;r9 ... address to actual entry in defer table
195         ;r10... address to defer table
196         ;r13 .. programmer address
197
198         ;load address of program
199         ldil r14, prog_mul@lo
200         ldih r14, prog_mul@hi
201
202         ldil r15, prog_consts@lo
203         ldih r15, prog_consts@hi
204
205         ;backup defer table address
206         mov r10, r9
207         ;decrement address to input by 1
208         subi r1, r1, 1
209
210 vm_default:     
211 vm_loop:
212         ;increment input address
213         addi r1, r1, 1
214
215         ;store address of next instruction in table
216         stw r2, 0(r3)
217         ;increment instr. table
218         addi r3, r3, 4
219
220         ;load input
221         ldb r5, 0(r1)
222         ;we need to multiply input by 4 to get correct address offset
223         lls r0, r5, 2
224         ;calc position in jumptable
225         ldw r0, jumptable(r0)
226         ;jump to instr
227         brr r0
228
229 vm_eof:
230         ;load address of program
231         ldil r4, prog_eof@lo
232         ldih r4, prog_eof@hi
233         ;program instruction (2)
234         ldw r0, 0(r4)
235         stw r0, PDATA(r13)
236         ldw r0, 4(r4)
237         stw r0, PDATA(r13)
238
239         ;end of program
240         ;now it is time to clear up the defer table
241
242         ldil r7, prog_jmp@lo
243         ldih r7, prog_jmp@hi
244         ;load branch template
245         ldw r7, 12(r7)
246
247         ;if actual and base are equal, no entry
248         cmp r9, r10
249         ;return
250         reteq-
251
252 vm_defer:
253         ;load pointer to where to jump to
254         ldw r6, 0(r10)
255         ;load where to jump to
256         ldw r6, 0(r6)
257         ;load where to save from defer table
258         stw r8, 4(r10)
259
260         ;generate branch
261         sub r11, r6, r8
262         ;lrs r11, r11, 2
263         ;set the upper 16 bit 0
264         andx r11, 0xFFFF
265         ;shift to the position of imm in br
266         lls r11, r11, 7
267         or r6, r7, r11
268         
269         stw r8, PADDR(r13)      
270         stw r6, PDATA(r13)
271
272         addi r10, r10, 8
273         cmp r10, r9
274         reteq+
275         brnq- vm_defer
276
277 ;case *
278 ;42
279 vm_mul:
280         ;program instruction (14)
281         ldw r0, 0(r14)
282         PROGINSTR
283         ldw r0, 4(r14)
284         PROGINSTR
285         ldw r0, 8(r14)
286         PROGINSTR
287         ldw r0, 12(r14)
288         PROGINSTR
289         ldw r0, 16(r14)
290         PROGINSTR
291         ldw r0, 20(r14)
292         PROGINSTR
293         ldw r0, 24(r14)
294         PROGINSTR
295         ldw r0, 28(r14)
296         PROGINSTR
297         ldw r0, 32(r14)
298         PROGINSTR
299         ldw r0, 36(r14)
300         PROGINSTR
301         ldw r0, 40(r14)
302         PROGINSTR
303         ldw r0, 44(r14)
304         PROGINSTR
305         ldw r0, 48(r14)
306         PROGINSTR
307
308         ;increment address
309         addi r2, r2, 13
310
311         br+ vm_loop
312
313 ;case +
314 ;43
315 vm_add:
316         ;load address of program
317         ldil r4, prog_add@lo
318         ldih r4, prog_add@hi
319
320         ;program instruction (5)
321         ldw r0, 0(r4)
322         PROGINSTR
323         ldw r0, 4(r4)
324         PROGINSTR
325         ldw r0, 8(r4)
326         PROGINSTR
327         ldw r0, 12(r4)
328         PROGINSTR
329
330         ;increment address
331         addi r2, r2, 4
332
333         br+ vm_loop
334
335 ;case -
336 ;45
337 vm_sub:
338         ;load address of program
339         ldil r4, prog_sub@lo
340         ldih r4, prog_sub@hi
341
342         ;program instruction (5)
343         ldw r0, 0(r4)
344         PROGINSTR
345         ldw r0, 4(r4)
346         PROGINSTR
347         ldw r0, 8(r4)
348         PROGINSTR
349         ldw r0, 12(r4)
350         PROGINSTR
351
352         ;increment address
353         addi r2, r2, 4
354
355         br+ vm_loop
356
357 ;case 0 1 2 3 4 5 6 7 8 9
358 ;48-57
359 vm_consts:
360         ;program instruction (3)
361         ldw r0, 0(r15)
362         ;the first instr. loads r6 with the number
363         ;thus we shall emulate this
364
365         ;call number
366         subi r6, r5, 48
367         ;shift 3 bits left, as the immediate in ldi has
368         ;an offset of 3
369         lls r6, r6, 3
370         ;now 'add' this to the ldi
371         or r0, r0, r6
372
373         ;store this 'dynamic' instruction
374         PROGINSTR
375         ldw r0, 4(r15)
376         PROGINSTR
377
378         ;increment address
379         addi r2, r2, 2
380
381         br+ vm_loop
382
383 ;case <
384 ;60
385 vm_lessthan:
386         ;load address of program
387         ldil r4, prog_lessthan@lo
388         ldih r4, prog_lessthan@hi
389
390         ;program instruction (6)
391         ldw r0, 0(r4)
392         PROGINSTR
393         ldw r0, 4(r4)
394         PROGINSTR
395         ldw r0, 8(r4)
396         PROGINSTR
397         ldw r0, 12(r4)
398         PROGINSTR
399         ldw r0, 16(r4)
400         PROGINSTR
401
402         ;increment address
403         addi r2, r2, 5
404
405         br+ vm_loop
406
407 ;case D
408 ;68
409 vm_dup:
410         ldil r4, prog_dup@lo
411         ldih r4, prog_dup@hi
412
413         ;program instruction (3)
414         ldw r0, 0(r4)
415         PROGINSTR
416         ldw r0, 4(r4)
417         PROGINSTR
418
419         ;increment address
420         addi r2, r2, 2
421
422         br+ vm_loop
423
424 ;case I
425 ;73
426 vm_imm:
427         ;the following instructions calculate the immediate
428         ;load new high byte
429         ldb r6, 4(r1)
430         ;shift high byte
431         lls r6, r6, 8
432         ;load 2nd byte
433         ldb r7, 3(r1)
434         ;add to high byte
435         add r6, r6, r7
436         ;shift
437         lls r6, r6, 8
438         ;load
439         ldb r7, 2(r1)
440         ;add
441         add r6, r6, r7
442         ;shift
443         lls r6, r6, 8
444         ;load
445         ldb r7, 1(r1)
446         ;add
447         add r6, r6, r7
448
449         ;now we will generate ldih/l which will store this
450         ;immediate into a register
451
452         ;load address of program
453         ldil r4, prog_imm@lo
454         ldih r4, prog_imm@hi
455
456         ;save r6 to r7
457         mov r7, r6
458
459         ;generate 1st instr
460         ldw r0, 0(r4)
461         andx r6, 0xFFFF
462         lls r6, r6, 3
463         or r0, r0, r6
464         PROGINSTR
465
466         ;generate 2nd instr
467         ldw r0, 4(r4)
468         andxh r7, 0xFFFF
469         lrs r7, r7, 13
470         or r0, r0, r7
471         PROGINSTR
472
473         ;now we program the instructions that will save the
474         ;immediate onto the stack and increment the later
475
476         ldw r0, 8(r4)
477         PROGINSTR
478
479         ;increment address
480         addi r2, r2, 3
481
482         ;pc+4
483         addi r1, r1, 4
484         br+ vm_loop
485
486 ;case J
487 ;74
488 vm_jmp:
489         ;gfreit mi net ...
490         ;gespeicherte instrs sollten input indepentent sein
491         ;jumptable verwenden
492         ;fuer forward jumps muss deferrer table gemacht werden *puke*
493
494         ;load address of program
495         ldil r4, prog_jmp@lo
496         ldih r4, prog_jmp@hi
497
498         ;program instruction (2)
499         ;pop r6
500         ldw r0, 0(r4)
501         PROGINSTR
502
503         ;compare to 0
504         ;cmpi r6,0
505         ldw r0, 4(r4)
506         PROGINSTR
507
508         ;breq+ vm_next
509         ;is statically known
510         ldw r0, 8(r4)
511         PROGINSTR
512
513         ;we add the offset to this instruction
514         addi r8, r2, 3
515
516
517         ;we know calculate the jump destination
518         ;set r6 to 0 (to clear upper bytes)
519         ldis r6, 0
520         ;load pc+1 input
521         ldb r6, 1(r1)
522         ;compare input with neg. max of 8 bit
523         cmpi r6, 0x80
524         brlt- vm_possign
525
526
527
528         ;generate negativ offset
529         ldis r7, 0xFF00
530         ;r6 is now the 'real' negativ number
531         or r6, r6, r7
532         ;todo: testing showed (at least once) we are off by 2 instr.
533         ;addi r6, r6, 2
534         ;multiply by to get the offset
535         lls r6, r6, 2
536         ;generate address in table
537         add r6, r3, r6
538         ;r0 now has the target address
539         ;todo: 0-4?
540         ldw r0, 0(r6)
541         ;we calc the offset
542         sub r8, r0, r8
543         ;we shift 2 bits out, because rel. br takes instr.
544         ;count and not address amount ...
545         ;lrs r8, r8, 2
546         ;set the upper 16 bit 0
547         andx r8, 0xFFFF
548         ;shift to the position of imm in br
549         lls r8, r8, 7
550         ;load template br
551         ldw r0, 12(r4)
552         or r0, r0, r8
553         PROGINSTR
554
555         ;increment address
556         addi r2, r2, 4
557
558         br+ vm_loop
559
560
561 vm_possign:
562         ;we know save the address in the instrtable where the addr to jump to stands
563         ;the value doesn't exists at the moment, but it will at evaluation
564
565         ;save position to save the instr into defer table
566         stw r8, 4(r9)
567
568         ;we need one instruction to have the correct offset (?)
569         PROGINSTR
570
571         ;todo: check if -1 is needed
572         ;subi r6, r6, 1
573         ;multiply with 2 to get offset right
574         lls r6, r6, 2
575         ;add to current base
576         add r6, r3, r6
577         ;save the address to defer table
578         stw r6, 0(r9)
579         ;increment defer table address
580         addi r9, r9, 8
581         ;increment address
582         addi r2, r2, 4
583         br+ vm_loop
584
585 ;case P
586 ;80
587 vm_pop:
588         ;load address of program
589         ldil r4, prog_pop@lo
590         ldih r4, prog_pop@hi
591
592         ;program instruction (1)
593         ldw r0, 0(r4)
594         PROGINSTR
595
596         ;increment address
597         addi r2, r2, 1
598
599         br+ vm_loop
600
601 ;case X
602 ;88
603 vm_xch:
604         ;load address of program
605         ldil r4, prog_xch@lo
606         ldih r4, prog_xch@hi
607
608         ;program instruction (4)
609         ldw r0, 0(r4)
610         PROGINSTR
611         ldw r0, 4(r4)
612         PROGINSTR
613         ldw r0, 8(r4)
614         PROGINSTR
615         ldw r0, 12(r4)
616         PROGINSTR
617
618         ;increment address
619         addi r2, r2, 4
620
621         br+ vm_loop
622
623 ;case ~
624 ;126
625 vm_not:
626         ;load address of program
627         ldil r4, prog_not@lo
628         ldih r4, prog_not@hi
629
630         ;program instruction (3)
631         ldw r0, 0(r4)
632         PROGINSTR
633         ldw r0, 4(r4)
634         PROGINSTR
635         ldw r0, 8(r4)
636         PROGINSTR
637
638         ;increment address
639         addi r2, r2, 3
640
641         br+ vm_loop
642
643
644 .data
645 jumptable:
646 ;0
647 .fill 1, vm_eof/4
648 .fill 41, vm_default/4
649 ;42
650 .fill 1, vm_mul/4
651 ;43
652 .fill 1, vm_add/4
653 ;44
654 .fill 1, vm_default/4
655 ;45
656 .fill 1, vm_sub/4
657 ;46-47
658 .fill 2, vm_default/4
659 ;48-57
660 .fill 10, vm_consts/4
661 ;58-59
662 .fill 2, vm_default/4
663 ;60
664 .fill 1, vm_lessthan/4
665 ;61-67
666 .fill 7, vm_default/4
667 ;68
668 .fill 1, vm_dup/4
669 ;69-72
670 .fill 4, vm_default/4
671 ;73
672 .fill 1, vm_imm/4
673 ;74
674 .fill 1, vm_jmp/4
675 ;75-79
676 .fill 5, vm_default/4
677 ;80
678 .fill 1, vm_pop/4
679 ;81-87
680 .fill 7, vm_default/4
681 ;88
682 .fill 1, vm_xch/4
683 ;89-125
684 .fill 37, vm_default/4
685 ;126
686 .fill 1, vm_not/4
687 ;127-255
688 .fill 129, vm_default/4
689
690 ;we assume not more than 3 entries
691 defertable:
692 .fill 6, 0