.fill 42, 0
prog_eof:
-.ifill pop r0
+.ifill pop r7
+.ifill mov r0, r6
.ifill ret+
prog_mul:
-.ifill pop r6
.ifill pop r7
.ifill ldis r8, 0;0xed400004
.ifill mov r0, r7;0xe1038000
.ifill adddnz r8, r8, r6;0x00443001
.ifill subi r7, r7, 2;0xe1bb8010
.fill 0x0b7ffe83;brnz+ loop
-.ifill push r8
+.ifill mov r6, r8
prog_consts:
-.fill 0xed300004;ldis r6, CONST
.ifill push r6
+.fill 0xed300004;ldis r6, CONST
prog_add:
-.ifill pop r6
.ifill pop r7
-.ifill add r7, r7, r6;0xe03bb000
-.ifill push r7
+.ifill add r6, r7, r6;0xe03bb000
prog_sub:
-.ifill pop r6
.ifill pop r7
.ifill sub r7, r7, r6;0xe0bbb000
-.ifill push r7
+.ifill mov r6, r7
prog_lessthan:
-.ifill pop r6
.ifill pop r7
.ifill cmp r7, r6;0xec3b0000
-.ifill pushlt r14
-.ifill pushge r15
+.ifill movdlt r6, r14
+.ifill movge r6, r15
prog_dup:
-.ifill fetch r6
.ifill push r6
prog_jmp:
-.ifill pop r6
.ifill cmpi r6,0;0xecb00000
+.ifill pop r6
;static calced
.fill 1, 0x1b000103;breq- vm_next
.fill 1, 0xeb000003;br+ CONST
prog_imm:
+.ifill push r6
.fill 1, 0xed300000;ldil r6, CONST
.fill 1, 0xed300002;ldih r6, CONST
-.ifill push r6
prog_pop:
-.ifill disc
+.ifill pop r6
prog_xch:
-.ifill pop r6
.ifill pop r7
.ifill push r6
-.ifill push r7
+.ifill mov r6, r7
prog_not:
-.ifill pop r6
.ifill not r6;0xe4b7fffa
-.ifill push r6
.text
.org 0
;backup defer table address
mov r10, r9
- ;decrement address to input by 1
br+ vm_loop_1
vm_default:
stw r0, PDATA(r13)
ldw r0, 4(r4)
stw r0, PDATA(r13)
+ ldw r0, 8(r4)
+ stw r0, PDATA(r13)
;end of program
;now it is time to clear up the defer table
PROGINSTR
ldw r0, 44(r14)
PROGINSTR
- ldw r0, 48(r14)
- PROGINSTR
;increment address
- addi r2, r2, 13
+ addi r2, r2, 12
br+ vm_loop
PROGINSTR
ldw r0, 4(r4)
PROGINSTR
- ldw r0, 8(r4)
- PROGINSTR
- ldw r0, 12(r4)
- PROGINSTR
;increment address
- addi r2, r2, 4
+ addi r2, r2, 2
br+ vm_loop
PROGINSTR
ldw r0, 8(r4)
PROGINSTR
- ldw r0, 12(r4)
- PROGINSTR
;increment address
- addi r2, r2, 4
+ addi r2, r2, 3
br+ vm_loop
vm_consts:
;program instruction (3)
ldw r0, 0(r15)
+ PROGINSTR
+ ldw r0, 4(r15)
;the first instr. loads r6 with the number
;thus we shall emulate this
;store this 'dynamic' instruction
PROGINSTR
- ldw r0, 4(r15)
- PROGINSTR
;increment address
addi r2, r2, 2
PROGINSTR
ldw r0, 12(r4)
PROGINSTR
- ldw r0, 16(r4)
- PROGINSTR
;increment address
- addi r2, r2, 5
+ addi r2, r2, 4
br+ vm_loop
;program instruction (3)
ldw r0, 0(r4)
PROGINSTR
- ldw r0, 4(r4)
- PROGINSTR
;increment address
- addi r2, r2, 2
+ addi r2, r2, 1
br+ vm_loop
ldil r4, prog_imm@lo
ldih r4, prog_imm@hi
+ ldw r0, 0(r4)
+ PROGINSTR
+
;save r6 to r7
mov r7, r6
;generate 1st instr
- ldw r0, 0(r4)
+ ldw r0, 4(r4)
andx r6, 0xFFFF
lls r6, r6, 3
or r0, r0, r6
PROGINSTR
;generate 2nd instr
- ldw r0, 4(r4)
+ ldw r0, 8(r4)
andxh r7, 0xFFFF
lrs r7, r7, 13
or r0, r0, r7
PROGINSTR
- ;now we program the instructions that will save the
- ;immediate onto the stack and increment the later
-
- ldw r0, 8(r4)
- PROGINSTR
-
;increment address
addi r2, r2, 3
ldil r4, prog_jmp@lo
ldih r4, prog_jmp@hi
- ;program instruction (2)
- ;pop r6
+ ;compare to 0
+ ;cmpi r6,0
ldw r0, 0(r4)
PROGINSTR
- ;compare to 0
- ;cmpi r6,0
+ ;program instruction (2)
+ ;pop r6
ldw r0, 4(r4)
PROGINSTR
PROGINSTR
ldw r0, 8(r4)
PROGINSTR
- ldw r0, 12(r4)
- PROGINSTR
;increment address
- addi r2, r2, 4
+ addi r2, r2, 3
br+ vm_loop
;program instruction (3)
ldw r0, 0(r4)
PROGINSTR
- ldw r0, 4(r4)
- PROGINSTR
- ldw r0, 8(r4)
- PROGINSTR
;increment address
- addi r2, r2, 3
+ addi r2, r2, 1
br+ vm_loop
+++ /dev/null
-#define PROGINSTR stw r0, PDATA(r13)
-#include "dt_inc.s"
-.data
-.org 0x10
-inputdata:
-;8 * 8 4
-.fill 1, 0x382A3834
-;1 X * 8
-.fill 1, 0x31582A38
-;+ D X -
-.fill 1, 0x2B44582D
-;P \xF8 J D
-.fill 1, 0x50F84A44
-;+ * 8 6
-.fill 1, 0x2B2A3836
-;\000 \020 I D
-.fill 1, 0x00204944
-;~ < \000 \000
-.fill 1, 0x7E3C0000
-;8 P \005 J
-.fill 1, 0x3850054A
-;* 8
-.fill 1, 0x2A38
-
-stack:
-.fill 256, 0
-
-;needed for jumps
-;assuming that no more than 42 instr are used
-instrtable:
-.fill 42, 0
-
-prog_eof:
-.ifill pop r7
-.ifill mov r0, r6
-.ifill ret+
-
-prog_mul:
-.ifill pop r7
-.ifill ldis r8, 0;0xed400004
-.ifill mov r0, r7;0xe1038000
-.ifill andx r0, 1;0xe2800008
-.ifill adddnz r8, r8, r6;0x00443001
-.ifill subinz r7, r7, 1;0x01bb8008
-.ifill addizs r7, r7, 0;0x113b8000
-;loop:
-.ifill adddnz r8, r8, r6;0x00443001
-.ifill adddnz r8, r8, r6;0x00443001
-.ifill subi r7, r7, 2;0xe1bb8010
-.fill 0x0b7ffe83;brnz+ loop
-.ifill mov r6, r8
-
-prog_consts:
-.ifill push r6
-.fill 0xed300004;ldis r6, CONST
-
-prog_add:
-.ifill pop r7
-.ifill add r6, r7, r6;0xe03bb000
-
-prog_sub:
-.ifill pop r7
-.ifill sub r7, r7, r6;0xe0bbb000
-.ifill mov r6, r7
-
-prog_lessthan:
-.ifill pop r7
-.ifill cmp r7, r6;0xec3b0000
-.ifill movdlt r6, r14
-.ifill movge r6, r15
-
-prog_dup:
-.ifill push r6
-
-prog_jmp:
-.ifill cmpi r6,0;0xecb00000
-.ifill pop r6
-;static calced
-.fill 1, 0x1b000103;breq- vm_next
-.fill 1, 0xeb000003;br+ CONST
-
-prog_imm:
-.ifill push r6
-.fill 1, 0xed300000;ldil r6, CONST
-.fill 1, 0xed300002;ldih r6, CONST
-
-prog_pop:
-.ifill pop r6
-
-prog_xch:
-.ifill pop r7
-.ifill push r6
-.ifill mov r6, r7
-
-prog_not:
-.ifill not r6;0xe4b7fffa
-
-.text
-.org 0
-start:
- call+ main
- call+ main
- ret
-
-
-main:
-
- call+ u_init
- call+ u_recv_byte
-
- ; benchprolog
- call t_init
- call t_stop
- ldis r1, 0
- call t_valset
- call t_start
- ; /benchprolog
-
- ;set address of input
- ldis r1, inputdata@lo
- ldih r1, inputdata@hi
-
- ;set address of program start
- ldis r2, (prog_start/4)@lo
- ldih r2, (prog_start/4)@hi
-
- ;set address to instruction table
- ldis r3, instrtable@lo
- ldih r3, instrtable@hi
-
- ;set address to defer table
- ldis r9, defertable@lo
- ldih r9, defertable@hi
-
- ldis r13, PBASE@lo
- ldih r13, PBASE@hi
-
- ;set programmer address
- stw r2, PADDR(r13)
-
- ;call jit compiler
- call+ jit
-
- ;set address to stack
- ;ldil r3, stack@lo
- ;ldih r3, stack@hi
-
- ;make r15 a 0-register
- ldis r15, 0
- ;make r14 a 8-bit -1-register
- ldis r14, 0xFF
-
- ;call jit'ed prog
- call+ prog_start
-
- ; benchepilog
- push r0
- call+ t_init
- call+ t_stop
- call+ t_valget
- subi r0, r0, 0xd ; offset abziehen
- pop r3
- push r0
- push r3
- ; /benchepilog
-
- ;send result
- call+ u_init
- pop r1
- call u_send_byte
- call u_send_newline
- pop r1
- call u_send_uint
- call u_send_newline
-
- br+ main
-
-;first version only supports backward jumps
-jit:
- ;r1 ... address to input, every byte is a new input
- ; includes pc implicitly
- ;r2 ... address to program start
- ;r3 ... address of instruction table
- ;r4 ... gets loaded with instr. prog. addr.
- ;r5 ... input
- ;r9 ... address to actual entry in defer table
- ;r10... address to defer table
- ;r13 .. programmer address
-
- ;load address of program
- ldil r14, prog_mul@lo
- ldih r14, prog_mul@hi
-
- ldil r15, prog_consts@lo
- ldih r15, prog_consts@hi
-
- ;backup defer table address
- mov r10, r9
- br+ vm_loop_1
-
-vm_default:
-vm_loop:
- ;increment input address
- addi r1, r1, 1
-vm_loop_1:
- ;store address of next instruction in table
- stw r2, 0(r3)
- ;increment instr. table
- addi r3, r3, 4
-
- ;load input
- ldb r5, 0(r1)
- ;we need to multiply input by 4 to get correct address offset
- lls r0, r5, 2
- ;calc position in jumptable
- ldw r0, jumptable(r0)
- ;jump to instr
- brr r0
-
-vm_eof:
- ;load address of program
- ldil r4, prog_eof@lo
- ldih r4, prog_eof@hi
- ;program instruction (2)
- ldw r0, 0(r4)
- stw r0, PDATA(r13)
- ldw r0, 4(r4)
- stw r0, PDATA(r13)
- ldw r0, 8(r4)
- stw r0, PDATA(r13)
-
- ;end of program
- ;now it is time to clear up the defer table
-
- ldil r7, prog_jmp@lo
- ldih r7, prog_jmp@hi
- ;load branch template
- ldw r7, 12(r7)
-
- ;if actual and base are equal, no entry
- cmp r9, r10
- ;return
- reteq-
-
-vm_defer:
- ;load pointer to where to jump to
- ldw r6, 0(r10)
- ;load where to jump to
- ldw r6, 0(r6)
- ;load where to save from defer table
- stw r8, 4(r10)
-
- ;generate branch
- sub r11, r6, r8
- ;lrs r11, r11, 2
- ;set the upper 16 bit 0
- andx r11, 0xFFFF
- ;shift to the position of imm in br
- lls r11, r11, 7
- or r6, r7, r11
-
- stw r8, PADDR(r13)
- stw r6, PDATA(r13)
-
- addi r10, r10, 8
- cmp r10, r9
- reteq+
- br+ vm_defer
-
-;case *
-;42
-vm_mul:
- ;program instruction (14)
- ldw r0, 0(r14)
- PROGINSTR
- ldw r0, 4(r14)
- PROGINSTR
- ldw r0, 8(r14)
- PROGINSTR
- ldw r0, 12(r14)
- PROGINSTR
- ldw r0, 16(r14)
- PROGINSTR
- ldw r0, 20(r14)
- PROGINSTR
- ldw r0, 24(r14)
- PROGINSTR
- ldw r0, 28(r14)
- PROGINSTR
- ldw r0, 32(r14)
- PROGINSTR
- ldw r0, 36(r14)
- PROGINSTR
- ldw r0, 40(r14)
- PROGINSTR
- ldw r0, 44(r14)
- PROGINSTR
-
- ;increment address
- addi r2, r2, 12
-
- br+ vm_loop
-
-;case +
-;43
-vm_add:
- ;load address of program
- ldil r4, prog_add@lo
- ldih r4, prog_add@hi
-
- ;program instruction (5)
- ldw r0, 0(r4)
- PROGINSTR
- ldw r0, 4(r4)
- PROGINSTR
-
- ;increment address
- addi r2, r2, 2
-
- br+ vm_loop
-
-;case -
-;45
-vm_sub:
- ;load address of program
- ldil r4, prog_sub@lo
- ldih r4, prog_sub@hi
-
- ;program instruction (5)
- ldw r0, 0(r4)
- PROGINSTR
- ldw r0, 4(r4)
- PROGINSTR
- ldw r0, 8(r4)
- PROGINSTR
-
- ;increment address
- addi r2, r2, 3
-
- br+ vm_loop
-
-;case 0 1 2 3 4 5 6 7 8 9
-;48-57
-vm_consts:
- ;program instruction (3)
- ldw r0, 0(r15)
- PROGINSTR
- ldw r0, 4(r15)
- ;the first instr. loads r6 with the number
- ;thus we shall emulate this
-
- ;call number
- subi r6, r5, 48
- ;shift 3 bits left, as the immediate in ldi has
- ;an offset of 3
- lls r6, r6, 3
- ;now 'add' this to the ldi
- or r0, r0, r6
-
- ;store this 'dynamic' instruction
- PROGINSTR
-
- ;increment address
- addi r2, r2, 2
-
- br+ vm_loop
-
-;case <
-;60
-vm_lessthan:
- ;load address of program
- ldil r4, prog_lessthan@lo
- ldih r4, prog_lessthan@hi
-
- ;program instruction (6)
- ldw r0, 0(r4)
- PROGINSTR
- ldw r0, 4(r4)
- PROGINSTR
- ldw r0, 8(r4)
- PROGINSTR
- ldw r0, 12(r4)
- PROGINSTR
-
- ;increment address
- addi r2, r2, 4
-
- br+ vm_loop
-
-;case D
-;68
-vm_dup:
- ldil r4, prog_dup@lo
- ldih r4, prog_dup@hi
-
- ;program instruction (3)
- ldw r0, 0(r4)
- PROGINSTR
-
- ;increment address
- addi r2, r2, 1
-
- br+ vm_loop
-
-;case I
-;73
-vm_imm:
- ;the following instructions calculate the immediate
- ;load new high byte
- ldb r6, 4(r1)
- ;shift high byte
- lls r6, r6, 8
- ;load 2nd byte
- ldb r7, 3(r1)
- ;add to high byte
- add r6, r6, r7
- ;shift
- lls r6, r6, 8
- ;load
- ldb r7, 2(r1)
- ;add
- add r6, r6, r7
- ;shift
- lls r6, r6, 8
- ;load
- ldb r7, 1(r1)
- ;add
- add r6, r6, r7
-
- ;now we will generate ldih/l which will store this
- ;immediate into a register
-
- ;load address of program
- ldil r4, prog_imm@lo
- ldih r4, prog_imm@hi
-
- ldw r0, 0(r4)
- PROGINSTR
-
- ;save r6 to r7
- mov r7, r6
-
- ;generate 1st instr
- ldw r0, 4(r4)
- andx r6, 0xFFFF
- lls r6, r6, 3
- or r0, r0, r6
- PROGINSTR
-
- ;generate 2nd instr
- ldw r0, 8(r4)
- andxh r7, 0xFFFF
- lrs r7, r7, 13
- or r0, r0, r7
- PROGINSTR
-
- ;increment address
- addi r2, r2, 3
-
- ;pc+4
- addi r1, r1, 4
- br+ vm_loop
-
-;case J
-;74
-vm_jmp:
- ;gfreit mi net ...
- ;gespeicherte instrs sollten input indepentent sein
- ;jumptable verwenden
- ;fuer forward jumps muss deferrer table gemacht werden *puke*
-
- ;load address of program
- ldil r4, prog_jmp@lo
- ldih r4, prog_jmp@hi
-
- ;compare to 0
- ;cmpi r6,0
- ldw r0, 0(r4)
- PROGINSTR
-
- ;program instruction (2)
- ;pop r6
- ldw r0, 4(r4)
- PROGINSTR
-
- ;breq+ vm_next
- ;is statically known
- ldw r0, 8(r4)
- PROGINSTR
-
- ;we add the offset to this instruction
- addi r8, r2, 3
-
-
- ;we know calculate the jump destination
- ;set r6 to 0 (to clear upper bytes)
- ldis r6, 0
- ;load pc+1 input
- ldb r6, 1(r1)
- ;compare input with neg. max of 8 bit
- cmpi r6, 0x80
- brlt- vm_possign
-
-
-
- ;generate negativ offset
- ldis r7, 0xFF00
- ;r6 is now the 'real' negativ number
- or r6, r6, r7
- ;todo: testing showed (at least once) we are off by 2 instr.
- ;addi r6, r6, 2
- ;multiply by to get the offset
- lls r6, r6, 2
- ;generate address in table
- add r6, r3, r6
- ;r0 now has the target address
- ;todo: 0-4?
- ldw r0, 0(r6)
- ;we calc the offset
- sub r8, r0, r8
- ;we shift 2 bits out, because rel. br takes instr.
- ;count and not address amount ...
- ;lrs r8, r8, 2
- ;set the upper 16 bit 0
- andx r8, 0xFFFF
- ;shift to the position of imm in br
- lls r8, r8, 7
- ;load template br
- ldw r0, 12(r4)
- or r0, r0, r8
- PROGINSTR
-
- ;increment address
- addi r2, r2, 4
-
- br+ vm_loop
-
-
-vm_possign:
- ;we know save the address in the instrtable where the addr to jump to stands
- ;the value doesn't exists at the moment, but it will at evaluation
-
- ;save position to save the instr into defer table
- stw r8, 4(r9)
-
- ;we need one instruction to have the correct offset (?)
- PROGINSTR
-
- ;todo: check if -1 is needed
- ;subi r6, r6, 1
- ;multiply with 2 to get offset right
- lls r6, r6, 2
- ;add to current base
- add r6, r3, r6
- ;save the address to defer table
- stw r6, 0(r9)
- ;increment defer table address
- addi r9, r9, 8
- ;increment address
- addi r2, r2, 4
- br+ vm_loop
-
-;case P
-;80
-vm_pop:
- ;load address of program
- ldil r4, prog_pop@lo
- ldih r4, prog_pop@hi
-
- ;program instruction (1)
- ldw r0, 0(r4)
- PROGINSTR
-
- ;increment address
- addi r2, r2, 1
-
- br+ vm_loop
-
-;case X
-;88
-vm_xch:
- ;load address of program
- ldil r4, prog_xch@lo
- ldih r4, prog_xch@hi
-
- ;program instruction (4)
- ldw r0, 0(r4)
- PROGINSTR
- ldw r0, 4(r4)
- PROGINSTR
- ldw r0, 8(r4)
- PROGINSTR
-
- ;increment address
- addi r2, r2, 3
-
- br+ vm_loop
-
-;case ~
-;126
-vm_not:
- ;load address of program
- ldil r4, prog_not@lo
- ldih r4, prog_not@hi
-
- ;program instruction (3)
- ldw r0, 0(r4)
- PROGINSTR
-
- ;increment address
- addi r2, r2, 1
-
- br+ vm_loop
-
-
-.data
-jumptable:
-;0
-.fill 1, vm_eof/4
-.fill 41, vm_default/4
-;42
-.fill 1, vm_mul/4
-;43
-.fill 1, vm_add/4
-;44
-.fill 1, vm_default/4
-;45
-.fill 1, vm_sub/4
-;46-47
-.fill 2, vm_default/4
-;48-57
-.fill 10, vm_consts/4
-;58-59
-.fill 2, vm_default/4
-;60
-.fill 1, vm_lessthan/4
-;61-67
-.fill 7, vm_default/4
-;68
-.fill 1, vm_dup/4
-;69-72
-.fill 4, vm_default/4
-;73
-.fill 1, vm_imm/4
-;74
-.fill 1, vm_jmp/4
-;75-79
-.fill 5, vm_default/4
-;80
-.fill 1, vm_pop/4
-;81-87
-.fill 7, vm_default/4
-;88
-.fill 1, vm_xch/4
-;89-125
-.fill 37, vm_default/4
-;126
-.fill 1, vm_not/4
-;127-255
-.fill 129, vm_default/4
-
-;we assume not more than 3 entries
-defertable:
-.fill 6, 0