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