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