a786bf4c80297dbf013c037d493247958522b62e
[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 .ifill ldw r0, 0-4(r3);0xE701FFFC
33 .ifill ret+
34
35 prog_mul:
36 .ifill subi r3, r3, 4;0xE1998020
37 .ifill ldw r6, 0(r3);0xe7318000
38 .ifill ldw r7, 0-4(r3);0xe739fffc
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 stw r8, 0-4(r3);0xe7c1fffc
51
52 prog_consts:
53 .fill 0xed300004;ldis r6, CONST
54 .ifill stw r6, 0(r3);0xe7b18000
55 .ifill addi r3, r3, 4;0xe1198020
56
57 prog_add:
58 .ifill subi r3, r3, 4;0xe1998020
59 .ifill ldw r6, 0(r3);0xe7318000
60 .ifill ldw r7, 0-4(r3);0xe739fffc
61 .ifill add r7, r7, r6;0xe03bb000
62 .ifill stw r7, 0-4(r3);0xe7b9fffc
63
64 prog_sub:
65 .ifill subi r3, r3, 4;0xe1998020
66 .ifill ldw r6, 0(r3);0xe7318000
67 .ifill ldw r7, 0-4(r3);0xe739fffc
68 .ifill sub r7, r7, r6;0xe0bbb000
69 .ifill stw r7, 0-4(r3);0xe7b9fffc
70
71 prog_lessthan:
72 .ifill subi r3, r3, 4;0xe1998020
73 .ifill ldw r6, 0(r3);0xe7318000
74 .ifill ldw r7, 0-4(r3);0xe739fffc
75 .ifill ldis r8, 0;0xed400004
76 .ifill cmp r7, r6;0xec3b0000
77 .ifill ldislt r8, 0xFF;0xbd4007fc
78 .ifill stw r8, 0-4(r3);0xe7c1fffc
79
80 prog_dup:
81 .ifill ldw r6, 0-4(r3);0xe731fffc
82 .ifill stw r6, 0(r3);0xe7b18000
83 .ifill addi r3, r3, 4;0xe1198020
84
85 prog_jmp:
86 .ifill subi r3, r3, 4;0xe1998020
87 .ifill ldw r6, 0(r3);0xe7318000
88 .ifill cmpi r6,0;0xecb00000
89 ;static calced
90 .fill 1, 0x1b000103;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 .ifill stw r6, 0(r3);0xe7b18000
97 .ifill addi r3, r3, 4;0xe1198020
98
99 prog_pop:
100 .ifill subi r3, r3, 4;0xe1998020
101
102 prog_xch:
103 .ifill ldw r6, 0-4(r3);0xe731fffc
104 .ifill ldw r7, 0-8(r3);0xe739fff8
105 .ifill stw r6, 0-8(r3);0xe7b1fff8
106 .ifill stw r7, 0-4(r3);0xe7b9fffc
107
108 prog_not:
109 .ifill ldw r6, 0-4(r3);0xe731fffc
110 .ifill not r6;0xe4b7fffa
111 .ifill stw r6, 0-4(r3);0xe7b1fffc
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, defertable@lo
129         ldih r9, defertable@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         lrs r11, r11, 2
213         ;set the upper 16 bit 0
214         andx r11, 0xFFFF
215         ;shift to the position of imm in br
216         lls r11, r11, 7
217         or r6, r7, r11
218         stx r6, 0(r8)
219
220         addi r10, r10, 8
221         cmp r10, r9
222         reteq+
223         brnq- vm_defer
224
225 ;case *
226 ;42
227 vm_mul:
228         ;load address of program
229         ldil r4, prog_mul@lo
230         ldih r4, prog_mul@hi
231
232         ;program instruction (14)
233         ldw r0, 0(r4)
234         stx r0, 0(r2)
235         ldw r0, 4(r4)
236         stx r0, 4(r2)
237         ldw r0, 8(r4)
238         stx r0, 8(r2)
239         ldw r0, 12(r4)
240         stx r0, 12(r2)
241         ldw r0, 16(r4)
242         stx r0, 16(r2)
243         ldw r0, 20(r4)
244         stx r0, 20(r2)
245         ldw r0, 24(r4)
246         stx r0, 24(r2)
247         ldw r0, 28(r4)
248         stx r0, 28(r2)
249         ldw r0, 32(r4)
250         stx r0, 32(r2)
251         ldw r0, 36(r4)
252         stx r0, 36(r2)
253         ldw r0, 40(r4)
254         stx r0, 40(r2)
255         ldw r0, 44(r4)
256         stx r0, 44(r2)
257         ldw r0, 48(r4)
258         stx r0, 48(r2)
259         ldw r0, 52(r4)
260         stx r0, 52(r2)
261
262         ;increment address
263         addi r2, r2, 56
264
265         br+ vm_loop
266
267 ;case +
268 ;43
269 vm_add:
270         ;load address of program
271         ldil r4, prog_add@lo
272         ldih r4, prog_add@hi
273
274         ;program instruction (5)
275         ldw r0, 0(r4)
276         stx r0, 0(r2)
277         ldw r0, 4(r4)
278         stx r0, 4(r2)
279         ldw r0, 8(r4)
280         stx r0, 8(r2)
281         ldw r0, 12(r4)
282         stx r0, 12(r2)
283         ldw r0, 16(r4)
284         stx r0, 16(r2)
285
286         ;increment address
287         addi r2, r2, 20
288
289         br+ vm_loop
290
291 ;case -
292 ;45
293 vm_sub:
294         ;load address of program
295         ldil r4, prog_sub@lo
296         ldih r4, prog_sub@hi
297
298         ;program instruction (5)
299         ldw r0, 0(r4)
300         stx r0, 0(r2)
301         ldw r0, 4(r4)
302         stx r0, 4(r2)
303         ldw r0, 8(r4)
304         stx r0, 8(r2)
305         ldw r0, 12(r4)
306         stx r0, 12(r2)
307         ldw r0, 16(r4)
308         stx r0, 16(r2)
309
310         ;increment address
311         addi r2, r2, 20
312
313         br+ vm_loop
314
315 ;case 0 1 2 3 4 5 6 7 8 9
316 ;48-57
317 vm_consts:
318         ;load address of program
319         ldil r4, prog_consts@lo
320         ldih r4, prog_consts@hi
321
322         ;program instruction (3)
323         ldw r0, 0(r4)
324         ;the first instr. loads r6 with the number
325         ;thus we shall emulate this
326
327         ;call number
328         subi r6, r5, 48
329         ;shift 3 bits left, as the immediate in ldi has
330         ;an offset of 3
331         lls r6, r6, 3
332         ;now 'add' this to the ldi
333         or r0, r0, r6
334
335         ;store this 'dynamic' instruction
336         stx r0, 0(r2)
337         ldw r0, 4(r4)
338         stx r0, 4(r2)
339         ldw r0, 8(r4)
340         stx r0, 8(r2)
341
342         ;increment address
343         addi r2, r2, 12
344
345         br+ vm_loop
346
347 ;case <
348 ;60
349 vm_lessthan:
350         ;load address of program
351         ldil r4, prog_lessthan@lo
352         ldih r4, prog_lessthan@hi
353
354         ;program instruction (7)
355         ldw r0, 0(r4)
356         stx r0, 0(r2)
357         ldw r0, 4(r4)
358         stx r0, 4(r2)
359         ldw r0, 8(r4)
360         stx r0, 8(r2)
361         ldw r0, 12(r4)
362         stx r0, 12(r2)
363         ldw r0, 16(r4)
364         stx r0, 16(r2)
365         ldw r0, 20(r4)
366         stx r0, 20(r2)
367         ldw r0, 24(r4)
368         stx r0, 24(r2)
369
370         ;increment address
371         addi r2, r2, 28
372
373         br+ vm_loop
374
375 ;case D
376 ;68
377 vm_dup:
378         ;load address of program
379         ldil r4, prog_dup@lo
380         ldih r4, prog_dup@hi
381
382         ;program instruction (3)
383         ldw r0, 0(r4)
384         stx r0, 0(r2)
385         ldw r0, 4(r4)
386         stx r0, 4(r2)
387         ldw r0, 8(r4)
388         stx r0, 8(r2)
389
390         ;increment address
391         addi r2, r2, 12
392
393         br+ vm_loop
394
395 ;case I
396 ;73
397 vm_imm:
398         ;the following instructions calculate the immediate
399         ;load new high byte
400         ldb r6, 4(r1)
401         ;shift high byte
402         lls r6, r6, 8
403         ;load 2nd byte
404         ldb r7, 3(r1)
405         ;add to high byte
406         add r6, r6, r7
407         ;shift
408         lls r6, r6, 8
409         ;load
410         ldb r7, 2(r1)
411         ;add
412         add r6, r6, r7
413         ;shift
414         lls r6, r6, 8
415         ;load
416         ldb r7, 1(r1)
417         ;add
418         add r6, r6, r7
419
420         ;now we will generate ldih/l which will store this
421         ;immediate into a register
422
423         ;load address of program
424         ldil r4, prog_imm@lo
425         ldih r4, prog_imm@hi
426
427         ;save r6 to r7
428         mov r7, r6
429
430         ;generate 1st instr
431         ldw r0, 0(r4)
432         andx r6, 0xFFFF
433         lls r6, r6, 3
434         or r0, r0, r6
435         stx r0, 0(r2)
436
437         ;generate 2nd instr
438         ldw r0, 4(r4)
439         andxh r7, 0xFFFF
440         lrs r7, r7, 13
441         or r0, r0, r7
442         stx r0, 4(r2)
443
444         ;now we program the instructions that will save the
445         ;immediate onto the stack and increment the later
446
447         ldw r0, 8(r4)
448         stx r0, 8(r2)
449         ldw r0, 12(r4)
450         stx r0, 12(r2)
451
452         ;increment address
453         addi r2, r2, 16
454
455         ;pc+4
456         addi r1, r1, 4
457         br+ vm_loop
458
459 ;case J
460 ;74
461 vm_jmp:
462         ;gfreit mi net ...
463         ;gespeicherte instrs sollten input indepentent sein
464         ;jumptable verwenden
465         ;fuer forward jumps muss deferrer table gemacht werden *puke*
466
467         ;load address of program
468         ldil r4, prog_jmp@lo
469         ldih r4, prog_jmp@hi
470
471         ;program instruction (3)
472         ;decrement sp
473         ;subi r3, r3, 4
474         ldw r0, 0(r4)
475         stx r0, 0(r2)
476         ;load sp
477         ;ldw r6, 0(r3)
478         ldw r0, 4(r4)
479         stx r0, 4(r2)
480         ;compare to 0
481         ;cmpi r6,0
482         ldw r0, 8(r4)
483         stx r0, 8(r2)
484
485         ;breq+ vm_next
486         ;is statically known
487         ldw r0, 12(r4)
488         stx r0, 12(r2)
489
490         ;r8 has now the current base
491         ;ldw r8, 0-4(r3)
492         ;we add the offset to this instruction
493         addi r8, r2, 16
494
495
496         ;we know calculate the jump destination
497         ;set r6 to 0 (to clear upper bytes)
498         ldis r6, 0
499         ;load pc+1 input
500         ldb r6, 1(r1)
501         ;compare input with neg. max of 8 bit
502         cmpi r6, 0x80
503         brlt- vm_possign
504
505
506
507         ;generate negativ offset
508         ldis r7, 0xFF00
509         ;r6 is now the 'real' negativ number
510         or r6, r6, r7
511         ;todo: testing showed (at least once) we are off by 2 instr.
512         ;addi r6, r6, 2
513         ;multiply by to get the offset
514         lls r6, r6, 2
515         ;generate address in table
516         add r6, r3, r6
517         ;r0 now has the target address
518         ;todo: 0-4?
519         ldw r0, 0(r6)
520         ;we calc the offset
521         sub r8, r0, r8
522         ;we shift 2 bits out, because rel. br takes instr.
523         ;count and not address amount ...
524         lrs r8, r8, 2
525         ;set the upper 16 bit 0
526         andx r8, 0xFFFF
527         ;shift to the position of imm in br
528         lls r8, r8, 7
529         ;load template br
530         ldw r0, 16(r4)
531         or r0, r0, r8
532         stx r0, 16(r2)
533
534         ;increment address
535         addi r2, r2, 20
536
537         br+ vm_loop
538
539
540 vm_possign:
541         ;we know save the address in the instrtable where the addr to jump to stands
542         ;the value doesn't exists at the moment, but it will at evaluation
543
544         ;save position to save the instr into defer table
545         stw r8, 4(r9)
546
547         ;todo: check if -1 is needed
548         ;subi r6, r6, 1
549         ;multiply with 2 to get offset right
550         lls r6, r6, 2
551         ;add to current base
552         add r6, r3, r6
553         ;save the address to defer table
554         stw r6, 0(r9)
555         ;increment defer table address
556         addi r9, r9, 8
557         ;increment address
558         addi r2, r2, 20
559         br+ vm_loop
560
561 ;case P
562 ;80
563 vm_pop:
564         ;load address of program
565         ldil r4, prog_pop@lo
566         ldih r4, prog_pop@hi
567
568         ;program instruction (1)
569         ldw r0, 0(r4)
570         stx r0, 0(r2)
571
572         ;increment address
573         addi r2, r2, 4
574
575         br+ vm_loop
576
577 ;case X
578 ;88
579 vm_xch:
580         ;load address of program
581         ldil r4, prog_xch@lo
582         ldih r4, prog_xch@hi
583
584         ;program instruction (4)
585         ldw r0, 0(r4)
586         stx r0, 0(r2)
587         ldw r0, 4(r4)
588         stx r0, 4(r2)
589         ldw r0, 8(r4)
590         stx r0, 8(r2)
591         ldw r0, 12(r4)
592         stx r0, 12(r2)
593
594         ;increment address
595         addi r2, r2, 16
596
597         br+ vm_loop
598
599 ;case ~
600 ;126
601 vm_not:
602         ;load address of program
603         ldil r4, prog_not@lo
604         ldih r4, prog_not@hi
605
606         ;program instruction (3)
607         ldw r0, 0(r4)
608         stx r0, 0(r2)
609         ldw r0, 4(r4)
610         stx r0, 4(r2)
611         ldw r0, 8(r4)
612         stx r0, 8(r2)
613
614         ;increment address
615         addi r2, r2, 12
616
617         br+ vm_loop
618
619 prog_start:
620
621 .data
622 jumptable:
623 ;0
624 .fill 1, vm_eof
625 .fill 41, vm_default
626 ;42
627 .fill 1, vm_mul
628 ;43
629 .fill 1, vm_add
630 ;44
631 .fill 1, vm_default
632 ;45
633 .fill 1, vm_sub
634 ;46-47
635 .fill 2, vm_default
636 ;48-57
637 .fill 10, vm_consts
638 ;58-59
639 .fill 2, vm_default
640 ;60
641 .fill 1, vm_lessthan
642 ;61-67
643 .fill 7, vm_default
644 ;68
645 .fill 1, vm_dup
646 ;69-72
647 .fill 4, vm_default
648 ;73
649 .fill 1, vm_imm
650 ;74
651 .fill 1, vm_jmp
652 ;75-79
653 .fill 5, vm_default
654 ;80
655 .fill 1, vm_pop
656 ;81-87
657 .fill 7, vm_default
658 ;88
659 .fill 1, vm_xch
660 ;89-125
661 .fill 37, vm_default
662 ;126
663 .fill 1, vm_not
664 ;127-255
665 .fill 129, vm_default
666
667 ;we assume not more than 3 entries
668 defertable:
669 .fill 6, 0