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