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