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