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