deepjit: saved one instr overall ... 1664
[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         ;backup defer table address
160         mov r10, r9
161         ;decrement address to input by 1
162         subi r1, r1, 1
163
164 vm_default:     
165 vm_loop:
166         ;increment input address
167         addi r1, r1, 1
168
169         ;store address of next instruction in table
170         stw r2, 0(r3)
171         ;increment instr. table
172         addi r3, r3, 4
173
174         ;load input
175         ldb r5, 0(r1)
176         ;we need to multiply input by 4 to get correct address offset
177         lls r0, r5, 2
178         ;calc position in jumptable
179         ldw r0, jumptable(r0)
180         ;jump to instr
181         brr r0
182
183 vm_eof:
184         ;load address of program
185         ldil r4, prog_eof@lo
186         ldih r4, prog_eof@hi
187         ;program instruction (2)
188         ldw r0, 0(r4)
189         stx r0, 0(r2)
190         ldw r0, 4(r4)
191         stx r0, 4(r2)
192
193         ;end of program
194         ;now it is time to clear up the defer table
195
196         ldil r7, prog_jmp@lo
197         ldih r7, prog_jmp@hi
198         ;load branch template
199         ldw r7, 16(r7)
200
201         ;if actual and base are equal, no entry
202         cmp r9, r10
203         ;return
204         reteq-
205
206 vm_defer:
207         ;load pointer to where to jump to
208         ldw r6, 0(r10)
209         ;load where to jump to
210         ldw r6, 0(r6)
211         ;load where to save from defer table
212         stw r8, 4(r10)
213
214         ;generate branch
215         sub r11, r6, r8
216         lrs r11, r11, 2
217         ;set the upper 16 bit 0
218         andx r11, 0xFFFF
219         ;shift to the position of imm in br
220         lls r11, r11, 7
221         or r6, r7, r11
222         stx r6, 0(r8)
223
224         addi r10, r10, 8
225         cmp r10, r9
226         reteq+
227         brnq- vm_defer
228
229 ;case *
230 ;42
231 vm_mul:
232         ;load address of program
233         ldil r4, prog_mul@lo
234         ldih r4, prog_mul@hi
235
236         ;program instruction (14)
237         ldw r0, 0(r4)
238         stx r0, 0(r2)
239         ldw r0, 4(r4)
240         stx r0, 4(r2)
241         ldw r0, 8(r4)
242         stx r0, 8(r2)
243         ldw r0, 12(r4)
244         stx r0, 12(r2)
245         ldw r0, 16(r4)
246         stx r0, 16(r2)
247         ldw r0, 20(r4)
248         stx r0, 20(r2)
249         ldw r0, 24(r4)
250         stx r0, 24(r2)
251         ldw r0, 28(r4)
252         stx r0, 28(r2)
253         ldw r0, 32(r4)
254         stx r0, 32(r2)
255         ldw r0, 36(r4)
256         stx r0, 36(r2)
257         ldw r0, 40(r4)
258         stx r0, 40(r2)
259         ldw r0, 44(r4)
260         stx r0, 44(r2)
261         ldw r0, 48(r4)
262         stx r0, 48(r2)
263         ldw r0, 52(r4)
264         stx r0, 52(r2)
265
266         ;increment address
267         addi r2, r2, 56
268
269         br+ vm_loop
270
271 ;case +
272 ;43
273 vm_add:
274         ;load address of program
275         ldil r4, prog_add@lo
276         ldih r4, prog_add@hi
277
278         ;program instruction (5)
279         ldw r0, 0(r4)
280         stx r0, 0(r2)
281         ldw r0, 4(r4)
282         stx r0, 4(r2)
283         ldw r0, 8(r4)
284         stx r0, 8(r2)
285         ldw r0, 12(r4)
286         stx r0, 12(r2)
287         ldw r0, 16(r4)
288         stx r0, 16(r2)
289
290         ;increment address
291         addi r2, r2, 20
292
293         br+ vm_loop
294
295 ;case -
296 ;45
297 vm_sub:
298         ;load address of program
299         ldil r4, prog_sub@lo
300         ldih r4, prog_sub@hi
301
302         ;program instruction (5)
303         ldw r0, 0(r4)
304         stx r0, 0(r2)
305         ldw r0, 4(r4)
306         stx r0, 4(r2)
307         ldw r0, 8(r4)
308         stx r0, 8(r2)
309         ldw r0, 12(r4)
310         stx r0, 12(r2)
311         ldw r0, 16(r4)
312         stx r0, 16(r2)
313
314         ;increment address
315         addi r2, r2, 20
316
317         br+ vm_loop
318
319 ;case 0 1 2 3 4 5 6 7 8 9
320 ;48-57
321 vm_consts:
322         ;load address of program
323         ldil r4, prog_consts@lo
324         ldih r4, prog_consts@hi
325
326         ;program instruction (3)
327         ldw r0, 0(r4)
328         ;the first instr. loads r6 with the number
329         ;thus we shall emulate this
330
331         ;call number
332         subi r6, r5, 48
333         ;shift 3 bits left, as the immediate in ldi has
334         ;an offset of 3
335         lls r6, r6, 3
336         ;now 'add' this to the ldi
337         or r0, r0, r6
338
339         ;store this 'dynamic' instruction
340         stx r0, 0(r2)
341         ldw r0, 4(r4)
342         stx r0, 4(r2)
343         ldw r0, 8(r4)
344         stx r0, 8(r2)
345
346         ;increment address
347         addi r2, r2, 12
348
349         br+ vm_loop
350
351 ;case <
352 ;60
353 vm_lessthan:
354         ;load address of program
355         ldil r4, prog_lessthan@lo
356         ldih r4, prog_lessthan@hi
357
358         ;program instruction (6)
359         ldw r0, 0(r4)
360         stx r0, 0(r2)
361         ldw r0, 4(r4)
362         stx r0, 4(r2)
363         ldw r0, 8(r4)
364         stx r0, 8(r2)
365         ldw r0, 12(r4)
366         stx r0, 12(r2)
367         ldw r0, 16(r4)
368         stx r0, 16(r2)
369         ldw r0, 20(r4)
370         stx r0, 20(r2)
371
372         ;increment address
373         addi r2, r2, 24
374
375         br+ vm_loop
376
377 ;case D
378 ;68
379 vm_dup:
380         ;load address of program
381         ldil r4, prog_dup@lo
382         ldih r4, prog_dup@hi
383
384         ;program instruction (3)
385         ldw r0, 0(r4)
386         stx r0, 0(r2)
387         ldw r0, 4(r4)
388         stx r0, 4(r2)
389         ldw r0, 8(r4)
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