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