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