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