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