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