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